Increase storage size of usdt constant to 64 bits
authorRichard Sanger <rsanger@wand.net.nz>
Wed, 3 Feb 2021 01:56:22 +0000 (14:56 +1300)
committeryonghong-song <ys114321@gmail.com>
Fri, 26 Feb 2021 16:43:03 +0000 (08:43 -0800)
Systemtap defines argument size as either 1, 2, 4, or 8 bytes
signed or unsigned. Thus the constant variable should be stored in
a long long instead of an int to ensure at least 8 bytes size.

src/cc/bcc_usdt.h
src/cc/usdt.h
src/cc/usdt/usdt_args.cc
src/python/bcc/libbcc.py
tests/cc/test_usdt_args.cc

index 7188c879e26ecabcad0e71910f04e88986e59aa7..bdabdfb7082ccf5451fb511fc4e4b000e68e0321 100644 (file)
@@ -54,7 +54,7 @@ struct bcc_usdt_location {
 struct bcc_usdt_argument {
     int size;
     int valid;
-    int constant;
+    long long constant;
     int deref_offset;
     const char *deref_ident;
     const char *base_register_name;
index bf1c0dc467483f2bc4bd52d4283b252b768d158b..25e21edc155aa49d0365d40b657bfc70eaa8bdc2 100644 (file)
@@ -46,7 +46,7 @@ static const std::string COMPILER_BARRIER =
 class Argument {
 private:
   optional<int> arg_size_;
-  optional<int> constant_;
+  optional<long long> constant_;
   optional<int> deref_offset_;
   optional<std::string> deref_ident_;
   optional<std::string> base_register_name_;
@@ -75,7 +75,7 @@ public:
     return index_register_name_;
   }
   const optional<int> scale() const { return scale_; }
-  const optional<int> constant() const { return constant_; }
+  const optional<long long> constant() const { return constant_; }
   const optional<int> deref_offset() const { return deref_offset_; }
 
   friend class ArgumentParser;
@@ -100,6 +100,13 @@ class ArgumentParser {
       *result = number;
     return endp - arg_;
   }
+  ssize_t parse_number(ssize_t pos, optional<long long> *result) {
+    char *endp;
+    long long number = (long long)strtoull(arg_ + pos, &endp, 0);
+    if (endp > arg_ + pos)
+      *result = number;
+    return endp - arg_;
+  }
   bool error_return(ssize_t error_start, ssize_t skip_start) {
     print_error(error_start);
     if (isspace(arg_[skip_start]))
index 1e239bd6e76fef3d531e9ff9a085198cb57ab811..5a33c8edb0a835a4e049626f0a70cc9036298e41 100644 (file)
@@ -64,7 +64,7 @@ bool Argument::assign_to_local(std::ostream &stream,
                                const std::string &binpath,
                                const optional<int> &pid) const {
   if (constant_) {
-    tfm::format(stream, "%s = %d;", local_name, *constant_);
+    tfm::format(stream, "%s = %lld;", local_name, *constant_);
     return true;
   }
 
@@ -228,7 +228,7 @@ bool ArgumentParser_aarch64::parse(Argument *dest) {
     dest->deref_offset_ = offset;
   } else {
     // Parse ...@<value>
-    optional<int> val;
+    optional<long long> val;
     new_pos = parse_number(cur_pos, &val);
     if (cur_pos == new_pos)
       return error_return(cur_pos, cur_pos);
@@ -268,7 +268,7 @@ bool ArgumentParser_powerpc64::parse(Argument *dest) {
     arg_str = &arg_[cur_pos_];
 
     if (std::regex_search(arg_str, matches, arg_op_regex_const)) {
-      dest->constant_ = stoi(matches.str(1));
+      dest->constant_ = (long long)stoull(matches.str(1));
     } else if (std::regex_search(arg_str, matches, arg_op_regex_reg)) {
       dest->base_register_name_ = "gpr[" + matches.str(1) + "]";
     } else if (std::regex_search(arg_str, matches, arg_op_regex_breg_off)) {
@@ -327,7 +327,7 @@ bool ArgumentParser_s390x::parse(Argument *dest) {
     cur_pos_ += matches.length(0);
 
     if (std::regex_search(arg_ + cur_pos_, matches, arg_op_regex_imm)) {
-      dest->constant_ = stoi(matches.str(1));
+      dest->constant_ = (long long)stoull(matches.str(1));
     } else if (std::regex_search(arg_ + cur_pos_, matches, arg_op_regex_reg)) {
       dest->base_register_name_ = "gprs[" + matches.str(1) + "]";
     } else if (std::regex_search(arg_ + cur_pos_, matches, arg_op_regex_mem)) {
index ef1718c64b7a5eb2efdf6532cf30ade66bd8626e..9cb0b1406f6cc63b010b2cdea06ee0dbccc3d266 100644 (file)
@@ -285,7 +285,7 @@ class bcc_usdt_argument(ct.Structure):
     _fields_ = [
             ('size', ct.c_int),
             ('valid', ct.c_int),
-            ('constant', ct.c_int),
+            ('constant', ct.c_longlong),
             ('deref_offset', ct.c_int),
             ('deref_ident', ct.c_char_p),
             ('base_register_name', ct.c_char_p),
index b8db58d256308091e53a050e3e8e33e81bc56c40..715328517b14ac527318f671d637cd572836c90f 100644 (file)
@@ -23,7 +23,7 @@ using std::experimental::optional;
 using std::experimental::nullopt;
 
 static void verify_register(USDT::ArgumentParser &parser, int arg_size,
-                            int constant) {
+                            long long constant) {
   USDT::Argument arg;
   REQUIRE(parser.parse(&arg));
   REQUIRE(arg.arg_size() == arg_size);
@@ -177,6 +177,8 @@ TEST_CASE("test usdt argument parsing", "[usdt]") {
 #elif defined(__x86_64__)
     USDT::ArgumentParser_x64 parser(
         "-4@$0 8@$1234 %rdi %rax %rsi "
+        "8@$9223372036854775806 8@$18446744073709551614 "
+        "-8@$-1 "
         "-8@%rbx 4@%r12 8@-8(%rbp) 4@(%rax) "
         "-4@global_max_action(%rip) "
         "8@24+mp_(%rip) "
@@ -191,6 +193,9 @@ TEST_CASE("test usdt argument parsing", "[usdt]") {
     verify_register(parser, 8, "di");
     verify_register(parser, 8, "ax");
     verify_register(parser, 8, "si");
+    verify_register(parser, 8, 9223372036854775806ll);
+    verify_register(parser, 8, (long long)18446744073709551614ull);
+    verify_register(parser, -8, -1);
     verify_register(parser, -8, "bx");
     verify_register(parser, 4, "r12");