Skip to content

Commit

Permalink
Python tracing won't work when the shebang line has a space like below:
Browse files Browse the repository at this point in the history
" #! /usr/bin/env python3 "

This patch makes uftrace to understand the above shebang as well.

Fixed: namhyung#1690
Signed-off-by: Gabriel Kim <[email protected]>
  • Loading branch information
GabrielKimm committed Aug 31, 2023
2 parents 0ff461e + b2ab34d commit a1d8cb1
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 38 deletions.
67 changes: 29 additions & 38 deletions libmcount/dynamic.c
Original file line number Diff line number Diff line change
Expand Up @@ -384,10 +384,17 @@ static bool match_pattern_module(char *pathname)
return ret;
}

static bool match_pattern_list(struct uftrace_mmap *map, char *soname, char *sym_name)
/**
* match_pattern_list - match a symbol name against a pattern list
* @map - memory map of the symbol
* @soname - name of the module
* @sym_name - name of the symbol
* @return - -1 if match negative, 1 if match positive, 0 if no match
*/
static int match_pattern_list(struct uftrace_mmap *map, char *soname, char *sym_name)
{
struct patt_list *pl;
bool ret = false;
int ret = 0;
char *libname = basename(map->libname);

list_for_each_entry(pl, &patterns, list) {
Expand All @@ -398,7 +405,7 @@ static bool match_pattern_list(struct uftrace_mmap *map, char *soname, char *sym
continue;

if (match_filter_pattern(&pl->patt, sym_name))
ret = pl->positive;
ret = pl->positive ? 1 : -1;
}

return ret;
Expand All @@ -410,7 +417,6 @@ static void parse_pattern_list(char *patch_funcs, char *def_mod, enum uftrace_pa
char *name;
int j;
struct patt_list *pl;
bool all_negative = true;

strv_split(&funcs, patch_funcs, ";");

Expand All @@ -421,10 +427,8 @@ static void parse_pattern_list(char *patch_funcs, char *def_mod, enum uftrace_pa

if (name[0] == '!')
name++;
else {
else
pl->positive = true;
all_negative = false;
}

delim = strchr(name, '@');
if (delim == NULL) {
Expand All @@ -439,20 +443,6 @@ static void parse_pattern_list(char *patch_funcs, char *def_mod, enum uftrace_pa
list_add_tail(&pl->list, &patterns);
}

/* prepend match-all pattern, if all patterns are negative */
if (all_negative) {
pl = xzalloc(sizeof(*pl));
pl->positive = true;
pl->module = xstrdup(def_mod);

if (ptype == PATT_REGEX)
init_filter_pattern(ptype, &pl->patt, ".");
else
init_filter_pattern(PATT_GLOB, &pl->patt, "*");

list_add(&pl->list, &patterns);
}

strv_free(&funcs);
}

Expand Down Expand Up @@ -487,12 +477,6 @@ static bool skip_sym(struct uftrace_symbol *sym, struct mcount_dynamic_info *mdi
if (sym->type != ST_LOCAL_FUNC && sym->type != ST_GLOBAL_FUNC && sym->type != ST_WEAK_FUNC)
return true;

if (!match_pattern_list(map, soname, sym->name)) {
if (mcount_unpatch_func(mdi, sym, &disasm) == 0)
stats.unpatch++;
return true;
}

return false;
}

Expand Down Expand Up @@ -559,6 +543,7 @@ static void patch_normal_func_matched(struct mcount_dynamic_info *mdi, struct uf
unsigned i;
struct uftrace_symbol *sym;
bool found = false;
int match;
char *soname = get_soname(map->libname);

symtab = &map->mod->symtab;
Expand All @@ -568,9 +553,15 @@ static void patch_normal_func_matched(struct mcount_dynamic_info *mdi, struct uf

if (skip_sym(sym, mdi, map, soname))
continue;

found = true;
mcount_patch_func_with_stats(mdi, sym);

match = match_pattern_list(map, soname, sym->name);
if (!match)
continue;
else if (match == 1)
mcount_patch_func_with_stats(mdi, sym);
else
mcount_unpatch_func(mdi, sym, NULL);
}

if (!found)
Expand Down Expand Up @@ -846,27 +837,27 @@ TEST_CASE(dynamic_pattern_list)
pr_dbg("check simple match with default module\n");
parse_pattern_list("abc;!def", "main", PATT_SIMPLE);

TEST_EQ(match_pattern_list(main_map, NULL, "abc"), true);
TEST_EQ(match_pattern_list(main_map, NULL, "def"), false);
TEST_EQ(match_pattern_list(other_map, NULL, "xyz"), false);
TEST_EQ(match_pattern_list(main_map, NULL, "abc"), 1);
TEST_EQ(match_pattern_list(main_map, NULL, "def"), -1);
TEST_EQ(match_pattern_list(other_map, NULL, "xyz"), 0);

release_pattern_list();

pr_dbg("check negative regex match with default module\n");
parse_pattern_list("!^a", "main", PATT_REGEX);

TEST_EQ(match_pattern_list(main_map, NULL, "abc"), false);
TEST_EQ(match_pattern_list(main_map, NULL, "def"), true);
TEST_EQ(match_pattern_list(other_map, NULL, "xyz"), false);
TEST_EQ(match_pattern_list(main_map, NULL, "abc"), -1);
TEST_EQ(match_pattern_list(main_map, NULL, "def"), 0);
TEST_EQ(match_pattern_list(other_map, NULL, "xyz"), 0);

release_pattern_list();

pr_dbg("check wildcard match with other module\n");
parse_pattern_list("*@other", "main", PATT_GLOB);

TEST_EQ(match_pattern_list(main_map, NULL, "abc"), false);
TEST_EQ(match_pattern_list(main_map, NULL, "def"), false);
TEST_EQ(match_pattern_list(other_map, NULL, "xyz"), true);
TEST_EQ(match_pattern_list(main_map, NULL, "abc"), 0);
TEST_EQ(match_pattern_list(main_map, NULL, "def"), 0);
TEST_EQ(match_pattern_list(other_map, NULL, "xyz"), 1);

release_pattern_list();

Expand Down
34 changes: 34 additions & 0 deletions utils/utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -606,6 +606,7 @@ char *str_trim(char *str)
return NULL;
str = str_ltrim(str);
str = str_rtrim(str);
str = str_mtrim(str);
return str;
}

Expand Down Expand Up @@ -640,6 +641,39 @@ char *str_rtrim(char *str)
return str;
}

/**
* str_mtrim - to trim middle spaces
* @str: input string
*
* This function make @str to middle trimmed @str
*/
char *str_mtrim(char *str)
{
if (!str)
return NULL;

char *read_ptr = str;
char *write_ptr = str;
int space_flag = 0;

while (*read_ptr != '\0') {
if (isspace((unsigned char)*read_ptr)) {
if (!space_flag) {
*write_ptr++ = ' ';
space_flag = 1;
}
}
else {
*write_ptr++ = *read_ptr;
space_flag = 0;
}
read_ptr++;
}

*write_ptr = '\0';
return str;
}

/**
* strv_split - split given string and construct a string vector
* @strv: string vector
Expand Down
1 change: 1 addition & 0 deletions utils/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,7 @@ void strv_free(struct strv *strv);
char *str_trim(char *str);
char *str_ltrim(char *str);
char *str_rtrim(char *str);
char *str_mtrim(char *str);

char **parse_cmdline(char *cmd, int *argc);
void free_parsed_cmdline(char **argv);
Expand Down

0 comments on commit a1d8cb1

Please sign in to comment.