Commit 50a66d23 authored by williangaspar's avatar williangaspar
parent 6da344b8
...@@ -53,7 +53,7 @@ This is a work in progress. If something is missing, check the bpftrace source t ...@@ -53,7 +53,7 @@ This is a work in progress. If something is missing, check the bpftrace source t
- [3. `time()`: Time](#3-time-time) - [3. `time()`: Time](#3-time-time)
- [4. `join()`: Join](#4-join-join) - [4. `join()`: Join](#4-join-join)
- [5. `str()`: Strings](#5-str-strings) - [5. `str()`: Strings](#5-str-strings)
- [6. `sym()`: Symbol Resolution, Kernel-Level](#6-str-symbol-resolution-kernel-level) - [6. `ksym()`: Symbol Resolution, Kernel-Level](#6-str-symbol-resolution-kernel-level)
- [7. `usym()`: Symbol Resolution, User-Level](#7-usym-symbol-resolution-user-level) - [7. `usym()`: Symbol Resolution, User-Level](#7-usym-symbol-resolution-user-level)
- [8. `kaddr()`: Address Resolution, Kernel-Level](#8-kaddr-address-resolution-kernel-level) - [8. `kaddr()`: Address Resolution, Kernel-Level](#8-kaddr-address-resolution-kernel-level)
- [9. `uaddr()`: Address Resolution, User-Level](#9-uaddr-address-resolution-user-level) - [9. `uaddr()`: Address Resolution, User-Level](#9-uaddr-address-resolution-user-level)
...@@ -1260,7 +1260,7 @@ Tracing block I/O sizes > 0 bytes ...@@ -1260,7 +1260,7 @@ Tracing block I/O sizes > 0 bytes
- `time(char *fmt)` - Print formatted time - `time(char *fmt)` - Print formatted time
- `join(char *arr[])` - Print the array - `join(char *arr[])` - Print the array
- `str(char *s [, int length])` - Returns the string pointed to by s - `str(char *s [, int length])` - Returns the string pointed to by s
- `sym(void *p)` - Resolve kernel address - `ksym(void *p)` - Resolve kernel address
- `usym(void *p)` - Resolve user space address - `usym(void *p)` - Resolve user space address
- `kaddr(char *name)` - Resolve kernel symbol name - `kaddr(char *name)` - Resolve kernel symbol name
- `uaddr(char *name)` - Resolve user-level symbol name - `uaddr(char *name)` - Resolve user-level symbol name
...@@ -1269,7 +1269,7 @@ Tracing block I/O sizes > 0 bytes ...@@ -1269,7 +1269,7 @@ Tracing block I/O sizes > 0 bytes
- `exit()` - Quit bpftrace - `exit()` - Quit bpftrace
- `cgroupid(char *path)` - Resolve cgroup ID - `cgroupid(char *path)` - Resolve cgroup ID
Some of these are asynchronous: the kernel queues the event, but some time later (milliseconds) it is processed in user-space. The asynchronous actions are: <tt>printf()</tt>, <tt>time()</tt>, and <tt>join()</tt>. Both <tt>sym()</tt> and <tt>usym()</tt>, as well as the variables <tt>kstack</tt> and </tt>ustack</tt>, record addresses synchronously, but then do symbol translation asynchronously. Some of these are asynchronous: the kernel queues the event, but some time later (milliseconds) it is processed in user-space. The asynchronous actions are: <tt>printf()</tt>, <tt>time()</tt>, and <tt>join()</tt>. Both <tt>ksym()</tt> and <tt>usym()</tt>, as well as the variables <tt>kstack</tt> and </tt>ustack</tt>, record addresses synchronously, but then do symbol translation asynchronously.
A selection of these are discussed in the following sections. A selection of these are discussed in the following sections.
...@@ -1374,14 +1374,14 @@ We can trace strings that are displayed in a bash shell. Some length tuning is e ...@@ -1374,14 +1374,14 @@ We can trace strings that are displayed in a bash shell. Some length tuning is e
<anon@anon-VirtualBox:~$ > <anon@anon-VirtualBox:~$ >
``` ```
## 6. `sym()`: Symbol resolution, kernel-level ## 6. `ksym()`: Symbol resolution, kernel-level
Syntax: `sym(addr)` Syntax: `ksym(addr)`
Examples: Examples:
``` ```
# ./build/src/bpftrace -e 'kprobe:do_nanosleep { printf("%s\n", sym(reg("ip"))); }' # ./build/src/bpftrace -e 'kprobe:do_nanosleep { printf("%s\n", ksym(reg("ip"))); }'
Attaching 1 probe... Attaching 1 probe...
do_nanosleep do_nanosleep
do_nanosleep do_nanosleep
...@@ -1444,7 +1444,7 @@ Syntax: `reg(char *name)` ...@@ -1444,7 +1444,7 @@ Syntax: `reg(char *name)`
Examples: Examples:
``` ```
# ./src/bpftrace -e 'kprobe:tcp_sendmsg { @[sym(reg("ip"))] = count(); }' # ./src/bpftrace -e 'kprobe:tcp_sendmsg { @[ksym(reg("ip"))] = count(); }'
Attaching 1 probe... Attaching 1 probe...
^C ^C
......
#pragma once #pragma once
#include <iostream>
#include <string> #include <string>
#include <vector> #include <vector>
#include <map> #include <map>
#include "utils.h"
#include "types.h" #include "types.h"
namespace bpftrace { namespace bpftrace {
namespace ast { namespace ast {
static bool PRINT_STACK_DEPRICATED = true;
class Visitor; class Visitor;
class Node { class Node {
...@@ -59,17 +57,7 @@ public: ...@@ -59,17 +57,7 @@ public:
class Builtin : public Expression { class Builtin : public Expression {
public: public:
explicit Builtin(std::string ident) : ident(ident) { explicit Builtin(std::string ident) : ident(is_deprecated(ident)) {}
if (ident == "stack") {
if (PRINT_STACK_DEPRICATED)
{
std::cerr << "warning: stack is deprecated and will be removed in the future. Use kstack instead" << std::endl;
PRINT_STACK_DEPRICATED = false;
}
this->ident = "kstack";
}
}
std::string ident; std::string ident;
int probe_id; int probe_id;
...@@ -78,8 +66,8 @@ public: ...@@ -78,8 +66,8 @@ public:
class Call : public Expression { class Call : public Expression {
public: public:
explicit Call(std::string &func) : func(func), vargs(nullptr) { } explicit Call(std::string &func) : func(is_deprecated(func)), vargs(nullptr) { }
Call(std::string &func, ExpressionList *vargs) : func(func), vargs(vargs) { } Call(std::string &func, ExpressionList *vargs) : func(is_deprecated(func)), vargs(vargs) { }
std::string func; std::string func;
ExpressionList *vargs; ExpressionList *vargs;
......
...@@ -425,7 +425,7 @@ void CodegenLLVM::visit(Call &call) ...@@ -425,7 +425,7 @@ void CodegenLLVM::visit(Call &call)
b_.SetInsertPoint(zero); b_.SetInsertPoint(zero);
expr_ = nullptr; expr_ = nullptr;
} }
else if (call.func == "sym") else if (call.func == "ksym")
{ {
// We want expr_ to just pass through from the child node - don't set it here // We want expr_ to just pass through from the child node - don't set it here
call.vargs->front()->accept(*this); call.vargs->front()->accept(*this);
......
...@@ -78,7 +78,7 @@ void SemanticAnalyser::visit(Builtin &builtin) ...@@ -78,7 +78,7 @@ void SemanticAnalyser::visit(Builtin &builtin)
if (type == ProbeType::kprobe || if (type == ProbeType::kprobe ||
type == ProbeType::kretprobe || type == ProbeType::kretprobe ||
type == ProbeType::tracepoint) type == ProbeType::tracepoint)
builtin.type = SizedType(Type::sym, 8); builtin.type = SizedType(Type::ksym, 8);
else if (type == ProbeType::uprobe || type == ProbeType::uretprobe) else if (type == ProbeType::uprobe || type == ProbeType::uretprobe)
builtin.type = SizedType(Type::usym, 16); builtin.type = SizedType(Type::usym, 16);
else else
...@@ -235,12 +235,12 @@ void SemanticAnalyser::visit(Call &call) ...@@ -235,12 +235,12 @@ void SemanticAnalyser::visit(Call &call)
} }
} }
} }
else if (call.func == "sym" || call.func == "usym") { else if (call.func == "ksym" || call.func == "usym") {
check_nargs(call, 1); check_nargs(call, 1);
check_arg(call, Type::integer, 0); check_arg(call, Type::integer, 0);
if (call.func == "sym") if (call.func == "ksym")
call.type = SizedType(Type::sym, 8); call.type = SizedType(Type::ksym, 8);
else if (call.func == "usym") else if (call.func == "usym")
call.type = SizedType(Type::usym, 16); call.type = SizedType(Type::usym, 16);
} }
......
...@@ -389,10 +389,10 @@ std::vector<std::unique_ptr<IPrintable>> BPFtrace::get_arg_values(const std::vec ...@@ -389,10 +389,10 @@ std::vector<std::unique_ptr<IPrintable>> BPFtrace::get_arg_values(const std::vec
std::make_unique<PrintableCString>( std::make_unique<PrintableCString>(
reinterpret_cast<char *>(arg_data+arg.offset))); reinterpret_cast<char *>(arg_data+arg.offset)));
break; break;
case Type::sym: case Type::ksym:
arg_values.push_back( arg_values.push_back(
std::make_unique<PrintableString>( std::make_unique<PrintableString>(
resolve_sym(*reinterpret_cast<uint64_t*>(arg_data+arg.offset)))); resolve_ksym(*reinterpret_cast<uint64_t*>(arg_data+arg.offset))));
break; break;
case Type::usym: case Type::usym:
arg_values.push_back( arg_values.push_back(
...@@ -882,8 +882,8 @@ int BPFtrace::print_map(IMap &map, uint32_t top, uint32_t div) ...@@ -882,8 +882,8 @@ int BPFtrace::print_map(IMap &map, uint32_t top, uint32_t div)
std::cout << get_stack(*(uint64_t*)value.data(), false, 8); std::cout << get_stack(*(uint64_t*)value.data(), false, 8);
else if (map.type_.type == Type::ustack) else if (map.type_.type == Type::ustack)
std::cout << get_stack(*(uint64_t*)value.data(), true, 8); std::cout << get_stack(*(uint64_t*)value.data(), true, 8);
else if (map.type_.type == Type::sym) else if (map.type_.type == Type::ksym)
std::cout << resolve_sym(*(uintptr_t*)value.data()); std::cout << resolve_ksym(*(uintptr_t*)value.data());
else if (map.type_.type == Type::usym) else if (map.type_.type == Type::usym)
std::cout << resolve_usym(*(uintptr_t*)value.data(), *(uint64_t*)(value.data() + 8)); std::cout << resolve_usym(*(uintptr_t*)value.data(), *(uint64_t*)(value.data() + 8));
else if (map.type_.type == Type::inet) else if (map.type_.type == Type::inet)
...@@ -1435,7 +1435,7 @@ std::string BPFtrace::get_stack(uint64_t stackidpid, bool ustack, int indent) ...@@ -1435,7 +1435,7 @@ std::string BPFtrace::get_stack(uint64_t stackidpid, bool ustack, int indent)
if (addr == 0) if (addr == 0)
break; break;
if (!ustack) if (!ustack)
stack << padding << resolve_sym(addr, true) << std::endl; stack << padding << resolve_ksym(addr, true) << std::endl;
else else
stack << padding << resolve_usym(addr, pid, true) << std::endl; stack << padding << resolve_usym(addr, pid, true) << std::endl;
} }
...@@ -1486,19 +1486,19 @@ std::vector<std::string> BPFtrace::split_string(std::string &str, char split_by) ...@@ -1486,19 +1486,19 @@ std::vector<std::string> BPFtrace::split_string(std::string &str, char split_by)
return elems; return elems;
} }
std::string BPFtrace::resolve_sym(uintptr_t addr, bool show_offset) std::string BPFtrace::resolve_ksym(uintptr_t addr, bool show_offset)
{ {
struct bcc_symbol sym; struct bcc_symbol ksym;
std::ostringstream symbol; std::ostringstream symbol;
if (!ksyms_) if (!ksyms_)
ksyms_ = bcc_symcache_new(-1, nullptr); ksyms_ = bcc_symcache_new(-1, nullptr);
if (bcc_symcache_resolve(ksyms_, addr, &sym) == 0) if (bcc_symcache_resolve(ksyms_, addr, &ksym) == 0)
{ {
symbol << sym.name; symbol << ksym.name;
if (show_offset) if (show_offset)
symbol << "+" << sym.offset; symbol << "+" << ksym.offset;
} }
else else
{ {
...@@ -1606,7 +1606,7 @@ std::string BPFtrace::resolve_inet(int af, uint64_t inet) ...@@ -1606,7 +1606,7 @@ std::string BPFtrace::resolve_inet(int af, uint64_t inet)
std::string BPFtrace::resolve_usym(uintptr_t addr, int pid, bool show_offset) std::string BPFtrace::resolve_usym(uintptr_t addr, int pid, bool show_offset)
{ {
struct bcc_symbol sym; struct bcc_symbol usym;
std::ostringstream symbol; std::ostringstream symbol;
struct bcc_symbol_option symopts; struct bcc_symbol_option symopts;
void *psyms; void *psyms;
...@@ -1627,11 +1627,11 @@ std::string BPFtrace::resolve_usym(uintptr_t addr, int pid, bool show_offset) ...@@ -1627,11 +1627,11 @@ std::string BPFtrace::resolve_usym(uintptr_t addr, int pid, bool show_offset)
psyms = pid_sym_[pid]; psyms = pid_sym_[pid];
} }
if (bcc_symcache_resolve(psyms, addr, &sym) == 0) if (bcc_symcache_resolve(psyms, addr, &usym) == 0)
{ {
symbol << sym.name; symbol << usym.name;
if (show_offset) if (show_offset)
symbol << "+" << sym.offset; symbol << "+" << usym.offset;
} }
else else
{ {
......
...@@ -58,7 +58,7 @@ public: ...@@ -58,7 +58,7 @@ public:
int clear_map_ident(const std::string &ident); int clear_map_ident(const std::string &ident);
int zero_map_ident(const std::string &ident); int zero_map_ident(const std::string &ident);
std::string get_stack(uint64_t stackidpid, bool ustack, int indent=0); std::string get_stack(uint64_t stackidpid, bool ustack, int indent=0);
std::string resolve_sym(uintptr_t addr, bool show_offset=false); std::string resolve_ksym(uintptr_t addr, bool show_offset=false);
std::string resolve_usym(uintptr_t addr, int pid, bool show_offset=false); std::string resolve_usym(uintptr_t addr, int pid, bool show_offset=false);
std::string resolve_inet(int af, uint64_t inet); std::string resolve_inet(int af, uint64_t inet);
std::string resolve_uid(uintptr_t addr); std::string resolve_uid(uintptr_t addr);
......
...@@ -75,8 +75,8 @@ std::string MapKey::argument_value(BPFtrace &bpftrace, ...@@ -75,8 +75,8 @@ std::string MapKey::argument_value(BPFtrace &bpftrace,
return bpftrace.get_stack(*(uint64_t*)data, false); return bpftrace.get_stack(*(uint64_t*)data, false);
case Type::ustack: case Type::ustack:
return bpftrace.get_stack(*(uint64_t*)data, true); return bpftrace.get_stack(*(uint64_t*)data, true);
case Type::sym: case Type::ksym:
return bpftrace.resolve_sym(*(uint64_t*)data); return bpftrace.resolve_ksym(*(uint64_t*)data);
case Type::usym: case Type::usym:
return bpftrace.resolve_usym(*(uint64_t*)data, *(uint64_t*)(arg_data + 8)); return bpftrace.resolve_usym(*(uint64_t*)data, *(uint64_t*)(arg_data + 8));
case Type::inet: case Type::inet:
......
...@@ -33,7 +33,7 @@ std::string verify_format_string(const std::string &fmt, std::vector<Field> args ...@@ -33,7 +33,7 @@ std::string verify_format_string(const std::string &fmt, std::vector<Field> args
for (int i=0; i<num_args; i++, token_iter++) for (int i=0; i<num_args; i++, token_iter++)
{ {
Type arg_type = args.at(i).type.type; Type arg_type = args.at(i).type.type;
if (arg_type == Type::sym || arg_type == Type::usym || arg_type == Type::probe || if (arg_type == Type::ksym || arg_type == Type::usym || arg_type == Type::probe ||
arg_type == Type::username || arg_type == Type::kstack || arg_type == Type::ustack || arg_type == Type::username || arg_type == Type::kstack || arg_type == Type::ustack ||
arg_type == Type::inet) arg_type == Type::inet)
arg_type = Type::string; // Symbols should be printed as strings arg_type = Type::string; // Symbols should be printed as strings
......
...@@ -46,7 +46,7 @@ std::string typestr(Type t) ...@@ -46,7 +46,7 @@ std::string typestr(Type t)
case Type::kstack: return "kstack"; break; case Type::kstack: return "kstack"; break;
case Type::ustack: return "ustack"; break; case Type::ustack: return "ustack"; break;
case Type::string: return "string"; break; case Type::string: return "string"; break;
case Type::sym: return "sym"; break; case Type::ksym: return "ksym"; break;
case Type::usym: return "usym"; break; case Type::usym: return "usym"; break;
case Type::inet: return "inet"; break; case Type::inet: return "inet"; break;
case Type::cast: return "cast"; break; case Type::cast: return "cast"; break;
......
...@@ -27,7 +27,7 @@ enum class Type ...@@ -27,7 +27,7 @@ enum class Type
kstack, kstack,
ustack, ustack,
string, string,
sym, ksym,
usym, usym,
cast, cast,
join, join,
......
...@@ -114,4 +114,27 @@ std::vector<std::string> get_kernel_cflags( ...@@ -114,4 +114,27 @@ std::vector<std::string> get_kernel_cflags(
return cflags; return cflags;
} }
std::string is_deprecated(std::string &str)
{
std::vector<DeprecatedName>::iterator item;
for (item = DEPRECATED_LIST.begin(); item != DEPRECATED_LIST.end(); item++)
{
if (str.compare(item->old_name) == 0)
{
if (item->show_warning)
{
std::cerr << "warning: " << item->old_name << " is deprecated and will be removed in the future. ";
std::cerr << "Use " << item->new_name << "instead." << std::endl;
item->show_warning = false;
}
return item->new_name;
}
}
return str;
}
} // namespace bpftrace } // namespace bpftrace
...@@ -2,9 +2,24 @@ ...@@ -2,9 +2,24 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include <iostream>
namespace bpftrace { namespace bpftrace {
struct DeprecatedName
{
std::string old_name;
std::string new_name;
bool show_warning = true;
};
static std::vector<DeprecatedName> DEPRECATED_LIST =
{
{ "stack", "kstack"},
{ "sym", "ksym"},
};
inline std::string GetProviderFromPath(std::string path); inline std::string GetProviderFromPath(std::string path);
bool has_wildcard(const std::string &str); bool has_wildcard(const std::string &str);
std::vector<int> get_online_cpus(); std::vector<int> get_online_cpus();
...@@ -12,6 +27,7 @@ std::vector<int> get_possible_cpus(); ...@@ -12,6 +27,7 @@ std::vector<int> get_possible_cpus();
std::vector<std::string> get_kernel_cflags( std::vector<std::string> get_kernel_cflags(
const char* uname_machine, const char* uname_machine,
const std::string& kdir); const std::string& kdir);
std::string is_deprecated(std::string &str);
} // namespace bpftrace } // namespace bpftrace
......
...@@ -29,8 +29,8 @@ BEFORE sleep 1s && /bin/sh -c 'exit 0' & ...@@ -29,8 +29,8 @@ BEFORE sleep 1s && /bin/sh -c 'exit 0' &
EXPECT P: /bin/sh EXPECT P: /bin/sh
TIMEOUT 5 TIMEOUT 5
NAME sym NAME ksym
RUN bpftrace -e 'kprobe:do_nanosleep { printf("%s\n", sym(reg("ip"))); exit();}' RUN bpftrace -e 'kprobe:do_nanosleep { printf("%s\n", ksym(reg("ip"))); exit();}'
EXPECT P: /bin/sh EXPECT P: /bin/sh
TIMEOUT 5 TIMEOUT 5
BEFORE sleep 1 && sleep 1 & BEFORE sleep 1 && sleep 1 &
......
...@@ -89,6 +89,7 @@ TEST(semantic_analyser, builtin_functions) ...@@ -89,6 +89,7 @@ TEST(semantic_analyser, builtin_functions)
test("kprobe:f { system(\"ls\\n\") }", 0); test("kprobe:f { system(\"ls\\n\") }", 0);
test("kprobe:f { join(0) }", 0); test("kprobe:f { join(0) }", 0);
test("kprobe:f { sym(0xffff) }", 0); test("kprobe:f { sym(0xffff) }", 0);
test("kprobe:f { ksym(0xffff) }", 0);
test("kprobe:f { usym(0xffff) }", 0); test("kprobe:f { usym(0xffff) }", 0);
test("kprobe:f { ntop(2, 0xffff) }", 0); test("kprobe:f { ntop(2, 0xffff) }", 0);
test("kprobe:f { reg(\"ip\") }", 0); test("kprobe:f { reg(\"ip\") }", 0);
...@@ -245,6 +246,11 @@ TEST(semantic_analyser, call_str_2_expr) ...@@ -245,6 +246,11 @@ TEST(semantic_analyser, call_str_2_expr)
TEST(semantic_analyser, call_sym) TEST(semantic_analyser, call_sym)
{ {
test("kprobe:f { ksym(arg0); }", 0);
test("kprobe:f { @x = ksym(arg0); }", 0);
test("kprobe:f { ksym(); }", 1);
test("kprobe:f { ksym(\"hello\"); }", 10);
test("kprobe:f { sym(arg0); }", 0); test("kprobe:f { sym(arg0); }", 0);
test("kprobe:f { @x = sym(arg0); }", 0); test("kprobe:f { @x = sym(arg0); }", 0);
test("kprobe:f { sym(); }", 1); test("kprobe:f { sym(); }", 1);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment