Skip to content

Commit 534a366

Browse files
committed
record: skip whitespaces after shebang for scripts
Python tracing won't work when the shebang line has a space like below: " #! /usr/bin/env python3 " This patch makes uftrace to understand the above shebang as well. Fixed: #1690 Signed-off-by: Gabriel Kim <[email protected]>
1 parent c7c58d7 commit 534a366

File tree

4 files changed

+51
-61
lines changed

4 files changed

+51
-61
lines changed

cmds/record.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -1625,7 +1625,7 @@ static void check_binary(struct uftrace_opts *opts)
16251625
if (!opts->force && !opts->patch)
16261626
pr_err_ns(SCRIPT_MSG, opts->exename);
16271627

1628-
script = str_ltrim(script);
1628+
script = str_trim(script);
16291629

16301630
/* ignore options */
16311631
p = strchr(script, ' ');
@@ -2188,7 +2188,7 @@ int do_child_exec(int ready, struct uftrace_opts *opts, int argc, char *argv[])
21882188
if (strstr(shebang, "python"))
21892189
is_python = true;
21902190
#endif
2191-
s = str_ltrim(shebang);
2191+
s = str_trim(shebang);
21922192

21932193
p = strchr(s, ' ');
21942194
if (p != NULL)

libmcount/dynamic.c

+29-38
Original file line numberDiff line numberDiff line change
@@ -384,10 +384,17 @@ static bool match_pattern_module(char *pathname)
384384
return ret;
385385
}
386386

387-
static bool match_pattern_list(struct uftrace_mmap *map, char *soname, char *sym_name)
387+
/**
388+
* match_pattern_list - match a symbol name against a pattern list
389+
* @map - memory map of the symbol
390+
* @soname - name of the module
391+
* @sym_name - name of the symbol
392+
* @return - -1 if match negative, 1 if match positive, 0 if no match
393+
*/
394+
static int match_pattern_list(struct uftrace_mmap *map, char *soname, char *sym_name)
388395
{
389396
struct patt_list *pl;
390-
bool ret = false;
397+
int ret = 0;
391398
char *libname = basename(map->libname);
392399

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

400407
if (match_filter_pattern(&pl->patt, sym_name))
401-
ret = pl->positive;
408+
ret = pl->positive ? 1 : -1;
402409
}
403410

404411
return ret;
@@ -410,7 +417,6 @@ static void parse_pattern_list(char *patch_funcs, char *def_mod, enum uftrace_pa
410417
char *name;
411418
int j;
412419
struct patt_list *pl;
413-
bool all_negative = true;
414420

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

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

422428
if (name[0] == '!')
423429
name++;
424-
else {
430+
else
425431
pl->positive = true;
426-
all_negative = false;
427-
}
428432

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

442-
/* prepend match-all pattern, if all patterns are negative */
443-
if (all_negative) {
444-
pl = xzalloc(sizeof(*pl));
445-
pl->positive = true;
446-
pl->module = xstrdup(def_mod);
447-
448-
if (ptype == PATT_REGEX)
449-
init_filter_pattern(ptype, &pl->patt, ".");
450-
else
451-
init_filter_pattern(PATT_GLOB, &pl->patt, "*");
452-
453-
list_add(&pl->list, &patterns);
454-
}
455-
456446
strv_free(&funcs);
457447
}
458448

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

490-
if (!match_pattern_list(map, soname, sym->name)) {
491-
if (mcount_unpatch_func(mdi, sym, &disasm) == 0)
492-
stats.unpatch++;
493-
return true;
494-
}
495-
496480
return false;
497481
}
498482

@@ -559,6 +543,7 @@ static void patch_normal_func_matched(struct mcount_dynamic_info *mdi, struct uf
559543
unsigned i;
560544
struct uftrace_symbol *sym;
561545
bool found = false;
546+
int match;
562547
char *soname = get_soname(map->libname);
563548

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

569554
if (skip_sym(sym, mdi, map, soname))
570555
continue;
571-
572556
found = true;
573-
mcount_patch_func_with_stats(mdi, sym);
557+
558+
match = match_pattern_list(map, soname, sym->name);
559+
if (!match)
560+
continue;
561+
else if (match == 1)
562+
mcount_patch_func_with_stats(mdi, sym);
563+
else
564+
mcount_unpatch_func(mdi, sym, NULL);
574565
}
575566

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

849-
TEST_EQ(match_pattern_list(main_map, NULL, "abc"), true);
850-
TEST_EQ(match_pattern_list(main_map, NULL, "def"), false);
851-
TEST_EQ(match_pattern_list(other_map, NULL, "xyz"), false);
840+
TEST_EQ(match_pattern_list(main_map, NULL, "abc"), 1);
841+
TEST_EQ(match_pattern_list(main_map, NULL, "def"), -1);
842+
TEST_EQ(match_pattern_list(other_map, NULL, "xyz"), 0);
852843

853844
release_pattern_list();
854845

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

858-
TEST_EQ(match_pattern_list(main_map, NULL, "abc"), false);
859-
TEST_EQ(match_pattern_list(main_map, NULL, "def"), true);
860-
TEST_EQ(match_pattern_list(other_map, NULL, "xyz"), false);
849+
TEST_EQ(match_pattern_list(main_map, NULL, "abc"), -1);
850+
TEST_EQ(match_pattern_list(main_map, NULL, "def"), 0);
851+
TEST_EQ(match_pattern_list(other_map, NULL, "xyz"), 0);
861852

862853
release_pattern_list();
863854

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

867-
TEST_EQ(match_pattern_list(main_map, NULL, "abc"), false);
868-
TEST_EQ(match_pattern_list(main_map, NULL, "def"), false);
869-
TEST_EQ(match_pattern_list(other_map, NULL, "xyz"), true);
858+
TEST_EQ(match_pattern_list(main_map, NULL, "abc"), 0);
859+
TEST_EQ(match_pattern_list(main_map, NULL, "def"), 0);
860+
TEST_EQ(match_pattern_list(other_map, NULL, "xyz"), 1);
870861

871862
release_pattern_list();
872863

utils/utils.c

+19-19
Original file line numberDiff line numberDiff line change
@@ -595,33 +595,33 @@ char *strjoin(char *left, char *right, const char *delim)
595595
}
596596

597597
/**
598-
* str_ltrim - to trim left spaces
598+
* str_trim - to trim all spaces
599599
* @str: input string
600600
*
601-
* This function make @str to left trimmed @str
601+
* This function make @str to right trimmed @str
602602
*/
603-
char *str_ltrim(char *str)
603+
char *str_trim(char *str)
604604
{
605+
int i = 0;
606+
int j = 0;
607+
bool spaceFound = false;
608+
605609
if (!str)
606610
return NULL;
607-
while (isspace((unsigned char)*str)) {
608-
str++;
611+
612+
while (str[j]) {
613+
if (str[j] != ' ' || !spaceFound) {
614+
str[i] = str[j];
615+
i++;
616+
spaceFound = (str[j] == ' ');
617+
}
618+
j++;
609619
}
610-
return str;
611-
}
612620

613-
/**
614-
* str_rtrim - to trim right spaces
615-
* @str: input string
616-
*
617-
* This function make @str to right trimmed @str
618-
*/
619-
char *str_rtrim(char *str)
620-
{
621-
char *p = strchr(str, '\0');
622-
while (--p >= str && isspace(*p))
623-
;
624-
*(p + 1) = '\0';
621+
if (i > 0 && str[i - 1] == ' ')
622+
i--;
623+
624+
str[i] = '\0';
625625
return str;
626626
}
627627

utils/utils.h

+1-2
Original file line numberDiff line numberDiff line change
@@ -389,8 +389,7 @@ void strv_append(struct strv *strv, const char *str);
389389
void strv_replace(struct strv *strv, int idx, const char *str);
390390
char *strv_join(struct strv *strv, const char *delim);
391391
void strv_free(struct strv *strv);
392-
char *str_ltrim(char *str);
393-
char *str_rtrim(char *str);
392+
char *str_trim(char *str);
394393

395394
char **parse_cmdline(char *cmd, int *argc);
396395
void free_parsed_cmdline(char **argv);

0 commit comments

Comments
 (0)