On 5 Nov 2013 02:02, "Yicheng" <qycqycqycqycqyc@xxxxxxxxx> wrote: > > Looks good! > The main concern in my view is the performance issue for ktap vm interrupter. > vm runs parse_events_resolve_symbol() to parse the symbol, but it may > be the unnecessary burden for vm because it can be calculated in parser > and written into bytecode. And I wonder whether or not the parse process > consumes a lot of time. I wasn't thinking about it. > > One suggestion about parse_events_resolve_symbol(): IMHO, strndup may > be executed after checking whether r is a number, or it may do useless > malloc operations when r is a number. Nice catch, I resent updated patch. Thanks. > > > 2013/11/4 Azat Khuzhin <a3at.mail@xxxxxxxxx> >> >> This will allow to don't hardcoding addresses of functions in ktap >> scripts, that use uprobes, but instead, use normal function names. >> >> Before this patch: >> $ ktap -e 'trace probe:/path/to/bin:0xDEADBEAF' # instead some real address >> >> After this path: >> $ ktap -e 'trace probe:/path/to/bin:foo' >> >> Works also for ret probes (%return) >> Requires libelf. >> >> Signed-off-by: Azat Khuzhin <a3at.mail@xxxxxxxxx> >> --- >> Makefile | 5 ++- >> include/ktap_types.h | 2 + >> userspace/eventdef.c | 34 +++++++++++++++ >> userspace/symbol.c | 114 +++++++++++++++++++++++++++++++++++++++++++++++++++ >> userspace/symbol.h | 32 +++++++++++++++ >> 5 files changed, 186 insertions(+), 1 deletion(-) >> create mode 100644 userspace/symbol.c >> create mode 100644 userspace/symbol.h >> >> diff --git a/Makefile b/Makefile >> index 372b41a..344c82a 100644 >> --- a/Makefile >> +++ b/Makefile >> @@ -59,6 +59,8 @@ $(UDIR)/tstring.o: $(INTP)/tstring.c $(INC)/* >> $(QUIET_CC)$(CC) $(DEBUGINFO_FLAG) $(KTAPC_CFLAGS) -o $@ -c $< >> $(UDIR)/object.o: $(INTP)/object.c $(INC)/* >> $(QUIET_CC)$(CC) $(DEBUGINFO_FLAG) $(KTAPC_CFLAGS) -o $@ -c $< >> +$(UDIR)/symbol.o: $(UDIR)/symbol.c $(INC)/* >> + $(QUIET_CC)$(CC) $(DEBUGINFO_FLAG) $(KTAPC_CFLAGS) -o $@ -c $< >> >> KTAPOBJS = >> KTAPOBJS += $(UDIR)/lex.o >> @@ -73,9 +75,10 @@ KTAPOBJS += $(UDIR)/opcode.o >> KTAPOBJS += $(UDIR)/table.o >> KTAPOBJS += $(UDIR)/tstring.o >> KTAPOBJS += $(UDIR)/object.o >> +KTAPOBJS += $(UDIR)/symbol.o >> >> ktap: $(KTAPOBJS) >> - $(QUIET_LINK)$(CC) $(KTAPC_CFLAGS) -o $@ $(KTAPOBJS) -lpthread >> + $(QUIET_LINK)$(CC) $(KTAPC_CFLAGS) -o $@ $(KTAPOBJS) -lpthread -lelf >> >> KMISC := /lib/modules/$(KVERSION)/ktapvm/ >> >> diff --git a/include/ktap_types.h b/include/ktap_types.h >> index 1dae9d8..4e19f0b 100644 >> --- a/include/ktap_types.h >> +++ b/include/ktap_types.h >> @@ -600,5 +600,7 @@ extern ktap_global_state dummy_global_state; >> #define KTAP_QL(x) "'" x "'" >> #define KTAP_QS KTAP_QL("%s") >> >> +#define STRINGIFY(type) #type >> + >> #endif /* __KTAP_TYPES_H__ */ >> >> diff --git a/userspace/eventdef.c b/userspace/eventdef.c >> index 76a68ac..dab964a 100644 >> --- a/userspace/eventdef.c >> +++ b/userspace/eventdef.c >> @@ -29,6 +29,7 @@ >> #include "../include/ktap_types.h" >> #include "../include/ktap_opcodes.h" >> #include "ktapc.h" >> +#include "symbol.h" >> >> static char tracing_events_path[] = "/sys/kernel/debug/tracing/events"; >> >> @@ -305,6 +306,35 @@ static int parse_events_add_kprobe(char *old_event) >> >> #define UPROBE_EVENTS_PATH "/sys/kernel/debug/tracing/uprobe_events" >> >> +static char* parse_events_resolve_symbol(char *event, char *r) >> +{ >> + char *colon; >> + colon = strchr(event, ':'); >> + >> + char *binary = strndup(event, colon - event); >> + char *symbol = strndup(colon + 1 /* skip ":" */, >> + r ? (r - 1 /* skip "%" */ - colon) : strlen((const char *)colon)); >> + >> + /** >> + * Test whethere we have symbol address, or symbol name. >> + * If second, than we need to scan dso to resolve it. >> + */ >> + vaddr_t symbol_address; >> + if ((sscanf(symbol, "%lx", &symbol_address) != 1) && >> + (symbol_address = find_symbol(binary, symbol))) { >> + verbose_printf("symbol %s resolved to 0x%lx\n", >> + event, symbol_address); >> + >> + event = realloc(event, strlen(event) + (strlen(STRINGIFY(ULONG_MAX)))); >> + sprintf(event, "%s:0x%lx", binary, symbol_address); >> + } >> + >> + free(binary); >> + free(symbol); >> + >> + return event; >> +} >> + >> static int parse_events_add_uprobe(char *old_event) >> { >> static int event_seq = 0; >> @@ -326,6 +356,10 @@ static int parse_events_add_uprobe(char *old_event) >> r = strstr(event, "%return"); >> if (r) { >> memset(r, ' ', 7); >> + } >> + event = parse_events_resolve_symbol(event, r); >> + >> + if (r) { >> snprintf(probe_event, 128, "r:uprobes/kp%d %s", >> event_seq, event); >> } else >> diff --git a/userspace/symbol.c b/userspace/symbol.c >> new file mode 100644 >> index 0000000..23333b8 >> --- /dev/null >> +++ b/userspace/symbol.c >> @@ -0,0 +1,114 @@ >> +/* >> + * symbol.c >> + * >> + * This file is part of ktap by Jovi Zhangwei. >> + * >> + * Copyright (C) 2013 Azat Khuzhin <a3at.mail@xxxxxxxxx>. >> + * >> + * ktap is free software; you can redistribute it and/or modify it >> + * under the terms and conditions of the GNU General Public License, >> + * version 2, as published by the Free Software Foundation. >> + * >> + * ktap is distributed in the hope it will be useful, but WITHOUT >> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or >> + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for >> + * more details. >> + * >> + * You should have received a copy of the GNU General Public License along with >> + * this program; if not, write to the Free Software Foundation, Inc., >> + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. >> + */ >> + >> +#include "symbol.h" >> + >> +#include <stdio.h> >> +#include <stdlib.h> >> + >> +#include <sys/types.h> >> +#include <sys/stat.h> >> +#include <unistd.h> >> +#include <fcntl.h> >> +#include <string.h> >> + >> +#include <libelf.h> >> + >> + >> +/** >> + * @return v_addr of "LOAD" program header, that have zero offset. >> + */ >> +static vaddr_t find_load_address(Elf *elf) >> +{ >> + GElf_Phdr header; >> + size_t headers; >> + vaddr_t address = 0; >> + >> + elf_getphdrnum(elf, &headers); >> + while (headers-- > 0) { >> + gelf_getphdr(elf, headers, &header); >> + if (header.p_type != PT_LOAD || header.p_offset != 0) >> + continue; >> + >> + address = header.p_vaddr; >> + break; >> + } >> + >> + return address; >> +} >> + >> +static vaddr_t search_symbol(Elf *elf, const char *symbol) >> +{ >> + Elf_Data *elf_data = NULL; >> + Elf_Scn *scn = NULL; >> + GElf_Sym sym; >> + GElf_Shdr shdr; >> + >> + vaddr_t load_address = find_load_address(elf); >> + >> + if (!load_address) >> + return 0; >> + >> + while ((scn = elf_nextscn(elf, scn))) { >> + int i, symbols; >> + char *current_symbol; >> + >> + gelf_getshdr(scn, &shdr); >> + >> + if (shdr.sh_type != SHT_SYMTAB) >> + continue; >> + >> + elf_data = elf_getdata(scn, elf_data); >> + symbols = shdr.sh_size / shdr.sh_entsize; >> + >> + for (i = 0; i < symbols; i++) { >> + gelf_getsym(elf_data, i, &sym); >> + >> + if (GELF_ST_TYPE(sym.st_info) != STT_FUNC) >> + continue; >> + >> + current_symbol = elf_strptr(elf, shdr.sh_link, sym.st_name); >> + if (!strcmp(current_symbol, symbol)) { >> + return (sym.st_value - load_address); >> + } >> + } >> + } >> + >> + return 0; >> +} >> + >> +vaddr_t find_symbol(const char *exec, const char *symbol) >> +{ >> + Elf *elf = NULL; >> + int fd = 0; >> + vaddr_t vaddr = 0; >> + >> + if (((fd = open(exec, O_RDONLY)) != -1) && >> + (elf_version(EV_CURRENT) != EV_NONE) && >> + (elf = elf_begin(fd, ELF_C_READ, NULL))) >> + vaddr = search_symbol(elf, symbol); >> + >> + if (elf) >> + elf_end(elf); >> + if (fd) >> + close(fd); >> + return vaddr; >> +} >> diff --git a/userspace/symbol.h b/userspace/symbol.h >> new file mode 100644 >> index 0000000..478ad2e >> --- /dev/null >> +++ b/userspace/symbol.h >> @@ -0,0 +1,32 @@ >> +/* >> + * symbol.h >> + * >> + * This file is part of ktap by Jovi Zhangwei. >> + * >> + * Copyright (C) 2013 Azat Khuzhin <a3at.mail@xxxxxxxxx>. >> + * >> + * ktap is free software; you can redistribute it and/or modify it >> + * under the terms and conditions of the GNU General Public License, >> + * version 2, as published by the Free Software Foundation. >> + * >> + * ktap is distributed in the hope it will be useful, but WITHOUT >> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or >> + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for >> + * more details. >> + * >> + * You should have received a copy of the GNU General Public License along with >> + * this program; if not, write to the Free Software Foundation, Inc., >> + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. >> + */ >> + >> +#include <gelf.h> // GElf_Addr >> + >> + >> +typedef GElf_Addr vaddr_t; >> + >> +/** >> + * Find symbol in DSO >> + * >> + * @return 0 on failure, otherwise address of symbol. >> + */ >> +vaddr_t find_symbol(const char *exec, const char *symbol); >> -- >> 1.8.4.rc3 >> >> > > > > -- > Sincerely, > Yicheng Qin