-
Notifications
You must be signed in to change notification settings - Fork 479
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
automatic argument/retval display for well-known functions #158
Conversation
Here is a example usage and output:
|
I would like to find a better way to specify arguments and retvals for a long list of functions. And their types as well. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for doing this. But I think we don't need to pass the auto arg list through the env. Both of uftrace and libmcount can have the list, so it can just check the name of function and use it for argspec.
libmcount/mcount.h
Outdated
@@ -114,7 +114,7 @@ struct mcount_shmem { | |||
}; | |||
|
|||
/* first 4 byte saves the actual size of the argbuf */ | |||
#define ARGBUF_SIZE 1024 | |||
#define ARGBUF_SIZE 16384 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this is needed since it's not for passing argpsec. It is used to save actual contents of arguments and return value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see. I just limited the maximum length to 48 in 1bed671 because some strings are too long to record. Thanks!
Hmm.. I don't clearly understand your word. I didn't pass auto arg list through env because it may exceed the limit of environment variable length. I just keep using
Sorry but I don't get your point here again. Can you please explain more in details? |
225220c
to
60ab035
Compare
Clearly saying that I passed auto arg list directly to |
Oh, sorry about the misunderstanding. I can see the code not passing but adding the arg string directly. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a incomplete arbitrary list of standard library functions. I'm not sure how to maintain this list - it'd be great if some conversion script can be provided as well. Also it should be considered that how this can be useful in a long term.
cmd-record.c
Outdated
@@ -352,9 +354,46 @@ static int fill_file_header(struct opts *opts, int status, struct rusage *rusage | |||
if (write(fd, &hdr, sizeof(hdr)) != (int)sizeof(hdr)) | |||
pr_err("writing header info failed"); | |||
|
|||
char *orig_args = opts->args; | |||
char *orig_retval = opts->retval; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I prefer declaring variables before any statement like in (old) C syntax.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done!
cmd-record.c
Outdated
|
||
if (orig_args) { | ||
alloc_size = strlen(auto_args_list) + strlen(orig_args) + 2; | ||
opts->args = (char*)malloc(alloc_size); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use xmalloc (and its friends) and you don't need to cast it in C.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done!
cmd-record.c
Outdated
opts->args = (char*)malloc(alloc_size); | ||
strncpy(opts->args, auto_args_list, alloc_size); | ||
} | ||
pr_dbg("opts->args = %s\n", opts->args); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the debug message, I think a level 1 message (pr_dbg
) should be used to describe high level actions. I don't want to too many messages when using -v
alone.
In this case, it may be like "auto arg is used" or "extending args using builtin auto-arg list". Messages like above can use level 2 or 3 according to the verbosity.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. I changed it to pr_dbg2
.
libmcount/mcount.c
Outdated
if (arg_env) { | ||
alloc_size = strlen(auto_args_list) + strlen(arg_env) + 2; | ||
argument_str = (char*)malloc(alloc_size); | ||
sprintf(argument_str, "%s;%s", auto_args_list, arg_env); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you can use xasprintf()
instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done!
libmcount/mcount.c
Outdated
else { | ||
alloc_size = strlen(auto_args_list) + 1; | ||
argument_str = (char*)malloc(alloc_size); | ||
strncpy(argument_str, auto_args_list, alloc_size); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And xstrdup()
for this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done!
utils/autoargs.h
Outdated
* TODO: need to write a script to generate this form from prototypes | ||
*/ | ||
static char *auto_args_list = "\ | ||
malloc@arg1;free@arg1;\ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
C concatenates adjacent string literals into one. Also you could also make it a const array rather than a pointer variable. So it could be:
static const char auto_arg_list[] =
"AAA"
"BBB"
"CCC"
;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I changed it as a single string and separated into many pieces of string literals.
60ab035
to
6de2824
Compare
@namhyung I appreciate your comments in details. I applied your suggestion and updated it as a working-in-progress status. I still need to think how to generate auto args/retvals list with a script. |
Besides that, I would like to remove library specifier when giving args/retval before writing |
libmcount/record.c
Outdated
@@ -267,6 +267,7 @@ static unsigned save_to_argbuf(void *argbuf, struct list_head *args_spec, | |||
if (str) { | |||
unsigned i; | |||
char *dst = ptr + 2; | |||
const unsigned str_limit = 48; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For this kind of magic number, I prefer using macro constant with capital letters. Also 48 seems to too small - I don't know what's the good size but 100 looks like reasonable for me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I also see a crash with a long string argument during uftrace dump
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For this kind of magic number, I prefer using macro constant with capital letters.
Okay. I will make it as capital letter.
Also 48 seems to too small - I don't know what's the good size but 100 looks like reasonable for me.
I also see a crash with a long string argument during uftrace dump.
I made it as 64 before but crashed when I run uftrace dump
. I'm not sure about it but /usr/bin/gcc
does a lot of string comparison that exceeds my expectation.
Yep, I'm working on that now.. |
6de2824
to
0f0ed4d
Compare
|
I appreciate that! |
3351468
to
9b7014e
Compare
FYI, here is some snippet of
In such cases, it may consume a lot of record data so I couldn't increase the limit more than 48. |
9b7014e
to
a1aaba9
Compare
I've added a script that generates The example usage is as follows:
Please take a look at it! |
a1aaba9
to
5111b99
Compare
Here is the example usage:
|
a076aa6
to
22639e2
Compare
@namhyung It seems that this work is almost done but it always generates |
22639e2
to
93cfb82
Compare
utils/gen-autoargs.py
Outdated
@@ -44,7 +44,7 @@ | |||
type_specifier.extend(["std::string"]) | |||
|
|||
# The contents of libnames will be made to genearte library name specifier for arg spec | |||
libnames = ["", "libstdc++"] | |||
libnames = ["", "libstdc++", "libc++", "libbfd", "libLLVM"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know this is a bit weird to add such libraries but this commit is added for reference. If library specifier is removed, then we don't need this so we can also make the args/retval list shorter.
Makefile
Outdated
@@ -193,6 +194,9 @@ $(filter-out $(objdir)/uftrace.o,$(UFTRACE_OBJS)): $(objdir)/%.o: $(srcdir)/%.c | |||
$(objdir)/version.h: PHONY | |||
@$(srcdir)/misc/version.sh $@ $(VERSION_GIT) | |||
|
|||
$(objdir)/autoargs.h: PHONY | |||
@$(objdir)/utils/gen-autoargs.py $(objdir)/utils/prototypes.h |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we don't need to run gen-autoargs.py
always. If we provide autoargs.h, it will run only after prototype.h was changed. Also I'd like put the script and prototype header in the "misc" directory rather than "utils".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi, I've just updated as you said. I removed the commit for Makefile
and added autoargs.h
instead. Also I moved those files to misc
. Thanks.
93cfb82
to
8771476
Compare
Unlike
|
@namhyung Thanks but how can I go back to the previous patch series in the same branch? I changed to directly add |
|
8771476
to
8ad4e27
Compare
Thanks! I've just updated as you said, especially modified |
This adds *.sw[opn], *.patch and .orig rules to .gitignore. Signed-off-by: Honggyu Kim <honggyu.kp@gmail.com>
This is a preparation for adding a new option --auto-args, which displays arguments / return values for known library functions such as libc functions. Signed-off-by: Honggyu Kim <honggyu.kp@gmail.com>
Since some of strings are too long to store inside buffer, it sometimes exceeds ARGBUF_SIZE and fails. This patch limits the maximum string size is to 48 with NULL to prevent such problems. Signed-off-by: Honggyu Kim <honggyu.kp@gmail.com>
This adds a list prototypes of well-known library functions in "prototypes.h" and its parser that generates uftrace format argspec. The usage is as follows: $ ./misc/gen-autoargs.py ./misc/prototypes.h Then it generates "autoargs.h" that can be directly included by uftrace for --auto-args option support. In the below example, "simple_prototypes.h" has only 5 functions. It can be passed to "gen-autoargs.py" and the output is as follows: $ cat simple_prototypes.h void *malloc(size_t size); void free(void* ptr); const char* strcpy(char* dest, const char* src); int open(const char* pathname, int flags); int pthread_mutex_lock(pthread_mutex_t *mutex); $ ./gen-autoargs.py simple_prototypes.h GEN autoargs.h $ cat autoargs.h ... static char *auto_args_list = "malloc@arg1/u;" "free@arg1/x;" "strcpy@arg1/s,arg2/s;" "open@arg1/s,arg2;" "pthread_mutex_lock@arg1/x;" ; static char *auto_retvals_list = "malloc@retval/x;" "strcpy@retval/s;" "open@retval;" "pthread_mutex_lock@retval;" ; Signed-off-by: Honggyu Kim <honggyu.kp@gmail.com>
autoargs.h is generated by "gen-autoargs.py" based on "prototypes.h". This patch adds the generated file and this will be updated as the list of functions are updated later on. Signed-off-by: Honggyu Kim <honggyu.kp@gmail.com>
Since gen-autoargs.py generates a very long list of args/retval list, uftrace fails to store the entire list into the current buffer. It needs a huge buffer to store the list to properly support --auto-args option. This patch expands the size 8 times bigger. Signed-off-by: Honggyu Kim <honggyu.kp@gmail.com>
"utils/prototypes.h" contains the prototypes of well-known library functions, especially libc functions. uftrace understandable argspec format is generated by "gen-autoargs.py" based on "utils/prototypes.h" file. Then the generated "autoargs.h" file is directly included by uftrace for --auto-args support. This patch adds automatic args/retval rules directly to uftrace when --auto-args is enabled. It allows uftrace to display args/retval even for distributed binaries without -pg or -finstrument-functions build. Signed-off-by: Honggyu Kim <honggyu.kp@gmail.com>
$ uftrace --auto-args tests/t-autoargs hello hello # DURATION TID FUNCTION [11503] | main() { 2.044 us [11503] | strlen("autoargs test") = 13; 1.583 us [11503] | calloc(1, 14) = 0x1b28a80; 1.193 us [11503] | free(0x1b28a80); 1.344 us [11503] | strcmp("hello", "hello") = 0; 4.056 us [11503] | puts("hello") = 6; 18.513 us [11503] | } /* main */ Signed-off-by: Honggyu Kim <honggyu.kp@gmail.com>
8ad4e27
to
4055bfc
Compare
Merged: aeeb2b3 |
Hi @namhyung and @Taeung
I'm writing some code for item 3 and I wrote a subset of working prototype.
I would like to ask you about the interface and internals.
--auto-args
is addedutils/autoargs.h
describes the list of arguments / retvals for well known library functionsuftrace info
.I would like to hear your comments.
Thanks,
Honggyu