From 529120e8fbb1102f4023104bfcd33e2a573d3d56 Mon Sep 17 00:00:00 2001 From: Guanlan Dai Date: Thu, 27 Jun 2013 15:00:33 -0700 Subject: [PATCH 01/15] add ngx-lua-shdict tool --- ngx-lua-shdict | 295 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 295 insertions(+) create mode 100755 ngx-lua-shdict diff --git a/ngx-lua-shdict b/ngx-lua-shdict new file mode 100755 index 0000000..11a08bf --- /dev/null +++ b/ngx-lua-shdict @@ -0,0 +1,295 @@ +#!/usr/bin/env perl + +# Copyright (C) Yichun Zhang (agentzh) +# Copyright (C) Guanlan Dai + +use 5.006001; +use strict; +use warnings; + +use Getopt::Long qw( GetOptions ); + +GetOptions("a=s", \(my $stap_args), + "d", \(my $dump_src), + "h", \(my $help), + "p=i", \(my $pid), + "n=s", \(my $zone), + "k=s", \(my $key)) + or die usage(); + +if ($help) { + print usage(); + exit; +} + +if (!$pid) { + die "No nginx process pid specified by the -p option\n"; +} + +if (!defined $stap_args) { + $stap_args = ''; +} + +if ($stap_args !~ /\b-D\s*MAXACTION=/) { + $stap_args .= " -DMAXACTION=100000" +} + +if ($stap_args !~ /\b-D\s*MAXMAPENTRIES=/) { + $stap_args .= " -DMAXMAPENTRIES=5000" +} + +if ($stap_args !~ /\b-D\s*MAXBACKTRACE=/) { + $stap_args .= " -DMAXBACKTRACE=200" +} + +if ($stap_args !~ /\b-D\s*MAXSTRINGLEN=2048/) { + $stap_args .= " -DMAXSTRINGLEN=2048" +} + +if ($stap_args !~ /\b-D\s*MAXSKIPPED=1024/) { + $stap_args .= " -DMAXSKIPPED=1024" +} + +if ($^O ne 'linux') { + die "Only linux is supported but I am on $^O.\n"; +} + +my $nginx_file = "/proc/$pid/exe"; +if (!-f $nginx_file) { + die "Nginx process $pid is not running or ", + "you do not have enough permissions.\n"; +} + +my $nginx_path = readlink $nginx_file; + + +my $ver = `stap --version 2>&1`; +if (!defined $ver) { + die "Systemtap not installed or its \"stap\" utility is not visible to the PATH environment: $!\n"; +} + +if ($ver =~ /version\s+(\d+\.\d+)/i) { + my $v = $1; + if ($v < 2.1) { + die "ERROR: at least systemtap 2.1 is required but found $v\n"; + } + +} else { + die "ERROR: unknown version of systemtap:\n$ver\n"; +} + + + +if (!$zone) { + die "ERROR: please specify a dict zone\n"; +} + +if (!$key) { + die "ERROR: please specify a key\n"; +} + +my $hash = crc32($key); +print $hash; + +my $preamble = <<_EOC_; +probe begin { + printf("Tracing %d ($nginx_path)...\\n\\n", target()) +} +_EOC_ +chop $preamble; + +my $zone_name_len = length $zone; +my $key_len = length $key; +my $quoted_zone = quote_str($zone); +my $LUA_TBOOLEAN = 1; +my $LUA_TNUMBER = 3; +my $LUA_TSTRING = 4; +my $node = qq{\@cast(node, "ngx_rbtree_node_t", "$nginx_path")}; +my $sd = qq{\@cast(sd, "ngx_http_lua_shdict_node_t", "$nginx_path")}; + +my $stap_src; + +$stap_src = <<_EOC_; +$preamble + +function ngx_http_lua_shdict_lookup(zone, hash, key) { + printf("zone addr :%d\\n", zone) + ctx = \@cast(zone, "ngx_shm_zone_t", "$nginx_path")->data + sh = \@cast(ctx, "ngx_http_lua_shdict_ctx_t", "$nginx_path")->sh + node = \@cast(sh, "ngx_http_lua_shdict_shctx_t", "$nginx_path")->rbtree->root + sentinel = \@cast(sh, "ngx_http_lua_shdict_shctx_t", "$nginx_path")->rbtree->sentinel + printf("ctx addr :%d\\n", ctx) + printf("node addr :%d\\n", node) + while (node != sentinel) { + + if (hash < $node->key) { + node = $node->left + continue + } + + if (hash > $node->key) { + node = $node->right + continue + } + sd = &$node->color + printf("sd addr %d\\n", sd) + data = $sd->data + data_str = text_str(user_string(data)) + data_key = substr(data_str, 0 , $key_len) + printf("data_key %s\\n", data_key) + if (data_key == "$key"){ + return sd + } else { + if(data_key < "$key") { + node = $node->left + } else { + node = $node->right + } + } + } + + return 0 +} + +probe process("$nginx_path").function("ngx_process_events_and_timers"), + process("$nginx_path").function("ngx_http_init_request") +{ + if (pid() == target()) { + + zone_found = 0 + begin = local_clock_us() + + part = &\@var("ngx_cycle\@ngx_cycle.c")->shared_memory->part + zone = \@cast(part, "ngx_list_part_t")->elts + for (i = 0; ; i++) { + if (i >= \@cast(part, "ngx_list_part_t")->nelts) { + if (\@cast(part, "ngx_list_part_t")->next == 0) { + break + } + + part = \@cast(part, "ngx_list_part_t")->next + zone = \@cast(part, "ngx_list_part_t")->elts + i = 0 + } + + shm = &\@cast(zone, "ngx_shm_zone_t")[i]->shm + + name = &\@cast(shm, "ngx_shm_t")->name + + if (\@cast(name, "ngx_str_t")->len != $zone_name_len) { + continue; + } + + zone_name = user_string_n(\@cast(name, "ngx_str_t")->data, $zone_name_len) + + if (zone_name != $quoted_zone) { + continue; + } + + sd = ngx_http_lua_shdict_lookup(zone, $hash, "$key") + + if (sd) { + printf("Key found!\\n"); + value_type = $sd->value_type; + printf("value_type is %d\\n", value_type) + data = $sd->data + $key_len; + printf("value data addr %d", data) + if (value_type == $LUA_TSTRING) { + printf("Data is\\n%s\\n", user_string(data)) + } else if (value_type == $LUA_TNUMBER) { + printf("Data is\\n%s", user_string(data)) + } else if (value_type == $LUA_TBOOLEAN) { + printf("Data is\\n%d\\n", data) + break; + } else { + printf("bad value type found for key $key in shared_dict $zone\\n") + } + } else { + printf("Key not found!\\n"); + } + + zone_found = 1 + break + } + + if (!zone_found) { + printf("shm zone \\"%s\\" not found.\\n", $quoted_zone) + } + + elapsed = local_clock_us() - begin + printf("\\n%d microseconds elapsed in the probe handler.\\n", elapsed) + + exit() + + } /* pid() == target() */ +} +_EOC_ + + +if ($dump_src) { + print $stap_src; + exit; +} + +open my $in, "|stap $stap_args -x $pid -" + or die "Cannot run stap: $!\n"; + +print $in $stap_src; + +close $in; + +sub usage { + return <<'_EOC_'; +Usage: + ngx-lua-shdict [optoins] + +Options: + -p Specify the nginx worker process pid. + -a Pass extra arguments to the stap utility. + -n Specify the dict. + -k Specify the key. + +Examples: + ngx-lua-shdict -p 12345 + ngx-lua-shdict -p 12345 -a '-DMAXACTION=100000' +_EOC_ +} + + +sub quote_str { + my $s = shift; + $s =~ s/\\/\\\\/g; + $s =~ s/"/\\"/g; + $s =~ s/\n/\\n/g; + $s =~ s/\t/\\t/g; + $s =~ s/\r/\\r/g; + return qq{"$s"}; +} + +sub crc32 { + my ($input, $init_value, $polynomial) = @_; + + $init_value = 0 unless (defined $init_value); + $polynomial = 0xedb88320 unless (defined $polynomial); + + my @lookup_table; + + for (my $i = 0; $i < 256; $i++) { + my $x = $i; + for (my $j = 0; $j < 8; $j++) { + if ($x & 1) { + $x = ($x >> 1) ^ $polynomial; + } else { + $x = $x >> 1; + } + } + push @lookup_table, $x; + } + my $crc = $init_value ^ 0xffffffff; + foreach my $x (unpack ('C*', $input)) { + $crc = (($crc >> 8) & 0xffffff) ^ $lookup_table[ ($crc ^ $x) & 0xff ]; + } + $crc = $crc ^ 0xffffffff; + + return $crc; +} From 3a3b2092b3cb43847607713960bf53d91daa12d9 Mon Sep 17 00:00:00 2001 From: Guanlan Dai Date: Thu, 27 Jun 2013 16:53:54 -0700 Subject: [PATCH 02/15] add raw support for shdict --- ngx-lua-shdict | 139 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 90 insertions(+), 49 deletions(-) diff --git a/ngx-lua-shdict b/ngx-lua-shdict index 11a08bf..daf1974 100755 --- a/ngx-lua-shdict +++ b/ngx-lua-shdict @@ -13,6 +13,7 @@ GetOptions("a=s", \(my $stap_args), "d", \(my $dump_src), "h", \(my $help), "p=i", \(my $pid), + "raw", \(my $raw), "n=s", \(my $zone), "k=s", \(my $key)) or die usage(); @@ -62,7 +63,6 @@ if (!-f $nginx_file) { my $nginx_path = readlink $nginx_file; - my $ver = `stap --version 2>&1`; if (!defined $ver) { die "Systemtap not installed or its \"stap\" utility is not visible to the PATH environment: $!\n"; @@ -78,8 +78,6 @@ if ($ver =~ /version\s+(\d+\.\d+)/i) { die "ERROR: unknown version of systemtap:\n$ver\n"; } - - if (!$zone) { die "ERROR: please specify a dict zone\n"; } @@ -89,15 +87,6 @@ if (!$key) { } my $hash = crc32($key); -print $hash; - -my $preamble = <<_EOC_; -probe begin { - printf("Tracing %d ($nginx_path)...\\n\\n", target()) -} -_EOC_ -chop $preamble; - my $zone_name_len = length $zone; my $key_len = length $key; my $quoted_zone = quote_str($zone); @@ -107,60 +96,133 @@ my $LUA_TSTRING = 4; my $node = qq{\@cast(node, "ngx_rbtree_node_t", "$nginx_path")}; my $sd = qq{\@cast(sd, "ngx_http_lua_shdict_node_t", "$nginx_path")}; +my $preamble; +my $print_result_func_def; +my $print_time_elasped_func_def; +my $set_timer_begin; + +if ($raw) { + $preamble = ""; + + $set_timer_begin = ""; + + $print_time_elasped_func_def = ""; + + $print_result_func_def = <<_EOC_; +function print_result(sd) { + if (sd) { + value_type = $sd->value_type; + data = $sd->data + $key_len; + if (value_type == $LUA_TSTRING) { + print(user_string(data)) + } else if (value_type == $LUA_TNUMBER) { + print(user_long(data)) + } else if (value_type == $LUA_TBOOLEAN) { + print(user_long(data)) + } else { + printf("bad value type found for key $key in shared_dict $zone\\n") + } + } else { + exit() + } +} +_EOC_ + +} else { + $preamble = <<_EOC_; +probe begin { + printf("Tracing %d ($nginx_path)...\\n\\n", target()) +} +_EOC_ + + $set_timer_begin = qq{begin = local_clock_us()}; + + $print_time_elasped_func_def = <<_EOC_; +elapsed = local_clock_us() - begin +printf("\\n%d microseconds elapsed in the probe handler.\\n", elapsed) +_EOC_ + + $print_result_func_def = <<_EOC_; +function print_result(sd) { + printf("zone: \\"$zone\\" key: \\"$key\\"\\n") + if (sd) { + value_type = $sd->value_type; + data = $sd->data + $key_len; + if (value_type == $LUA_TSTRING) { + printf("type: LUA_TSTRING\\n") + printf("value: %s\\n", text_str(user_string(data))) + } else if (value_type == $LUA_TNUMBER) { + printf("type: LUA_TNUMBER\\n") + printf("value: %d\\n", user_long(data)) + } else if (value_type == $LUA_TBOOLEAN) { + printf("type: LUA_TBOOLEAN\\n") + printf("value: %d\\n", user_long(data)) + } else { + printf("ERROR: Bad value type found for key $key in shared_dict $zone\\n") + } + } else { + printf("ERROR: key not found\\n"); + } +} +_EOC_ + +} + +chop $preamble; + my $stap_src; $stap_src = <<_EOC_; $preamble function ngx_http_lua_shdict_lookup(zone, hash, key) { - printf("zone addr :%d\\n", zone) ctx = \@cast(zone, "ngx_shm_zone_t", "$nginx_path")->data sh = \@cast(ctx, "ngx_http_lua_shdict_ctx_t", "$nginx_path")->sh node = \@cast(sh, "ngx_http_lua_shdict_shctx_t", "$nginx_path")->rbtree->root sentinel = \@cast(sh, "ngx_http_lua_shdict_shctx_t", "$nginx_path")->rbtree->sentinel - printf("ctx addr :%d\\n", ctx) - printf("node addr :%d\\n", node) + while (node != sentinel) { if (hash < $node->key) { node = $node->left continue } - if (hash > $node->key) { node = $node->right continue } + sd = &$node->color - printf("sd addr %d\\n", sd) data = $sd->data data_str = text_str(user_string(data)) data_key = substr(data_str, 0 , $key_len) - printf("data_key %s\\n", data_key) if (data_key == "$key"){ return sd } else { - if(data_key < "$key") { + if (data_key < "$key") { node = $node->left } else { node = $node->right } } } - return 0 } +$print_result_func_def + probe process("$nginx_path").function("ngx_process_events_and_timers"), process("$nginx_path").function("ngx_http_init_request") { if (pid() == target()) { zone_found = 0 - begin = local_clock_us() + + $set_timer_begin part = &\@var("ngx_cycle\@ngx_cycle.c")->shared_memory->part zone = \@cast(part, "ngx_list_part_t")->elts + for (i = 0; ; i++) { if (i >= \@cast(part, "ngx_list_part_t")->nelts) { if (\@cast(part, "ngx_list_part_t")->next == 0) { @@ -173,40 +235,17 @@ probe process("$nginx_path").function("ngx_process_events_and_timers"), } shm = &\@cast(zone, "ngx_shm_zone_t")[i]->shm - name = &\@cast(shm, "ngx_shm_t")->name - if (\@cast(name, "ngx_str_t")->len != $zone_name_len) { continue; } - zone_name = user_string_n(\@cast(name, "ngx_str_t")->data, $zone_name_len) - if (zone_name != $quoted_zone) { continue; } sd = ngx_http_lua_shdict_lookup(zone, $hash, "$key") - - if (sd) { - printf("Key found!\\n"); - value_type = $sd->value_type; - printf("value_type is %d\\n", value_type) - data = $sd->data + $key_len; - printf("value data addr %d", data) - if (value_type == $LUA_TSTRING) { - printf("Data is\\n%s\\n", user_string(data)) - } else if (value_type == $LUA_TNUMBER) { - printf("Data is\\n%s", user_string(data)) - } else if (value_type == $LUA_TBOOLEAN) { - printf("Data is\\n%d\\n", data) - break; - } else { - printf("bad value type found for key $key in shared_dict $zone\\n") - } - } else { - printf("Key not found!\\n"); - } + print_result(sd) zone_found = 1 break @@ -216,8 +255,8 @@ probe process("$nginx_path").function("ngx_process_events_and_timers"), printf("shm zone \\"%s\\" not found.\\n", $quoted_zone) } - elapsed = local_clock_us() - begin - printf("\\n%d microseconds elapsed in the probe handler.\\n", elapsed) + + $print_time_elasped_func_def exit() @@ -246,12 +285,14 @@ Usage: Options: -p Specify the nginx worker process pid. -a Pass extra arguments to the stap utility. - -n Specify the dict. + -d Dump out the systemtap script source. + -n Specify the zone. -k Specify the key. + --raw Raw output. Examples: ngx-lua-shdict -p 12345 - ngx-lua-shdict -p 12345 -a '-DMAXACTION=100000' + ngx-lua-shdict -p 12345 -n dogs -k Jim _EOC_ } From ecd18e706ee6cd3a1270aca0f9bf8971893208ce Mon Sep 17 00:00:00 2001 From: Guanlan Dai Date: Thu, 27 Jun 2013 17:45:11 -0700 Subject: [PATCH 03/15] modify n to dict and add some newline --- ngx-lua-shdict | 62 +++++++++++++++++++++++++++++++------------------- 1 file changed, 39 insertions(+), 23 deletions(-) diff --git a/ngx-lua-shdict b/ngx-lua-shdict index daf1974..ffaf0df 100755 --- a/ngx-lua-shdict +++ b/ngx-lua-shdict @@ -14,8 +14,8 @@ GetOptions("a=s", \(my $stap_args), "h", \(my $help), "p=i", \(my $pid), "raw", \(my $raw), - "n=s", \(my $zone), - "k=s", \(my $key)) + "dict=s", \(my $dict), + "key=s", \(my $key)) or die usage(); if ($help) { @@ -78,7 +78,7 @@ if ($ver =~ /version\s+(\d+\.\d+)/i) { die "ERROR: unknown version of systemtap:\n$ver\n"; } -if (!$zone) { +if (!$dict) { die "ERROR: please specify a dict zone\n"; } @@ -87,14 +87,16 @@ if (!$key) { } my $hash = crc32($key); -my $zone_name_len = length $zone; +my $dict_name_len = length $dict; my $key_len = length $key; -my $quoted_zone = quote_str($zone); +my $quoted_zone = quote_str($dict); my $LUA_TBOOLEAN = 1; my $LUA_TNUMBER = 3; my $LUA_TSTRING = 4; +my $part = qq{\@cast(part, "ngx_list_part_t")}; my $node = qq{\@cast(node, "ngx_rbtree_node_t", "$nginx_path")}; my $sd = qq{\@cast(sd, "ngx_http_lua_shdict_node_t", "$nginx_path")}; +my $sh = qq{\@cast(sh, "ngx_http_lua_shdict_shctx_t", "$nginx_path")}; my $preamble; my $print_result_func_def; @@ -113,15 +115,20 @@ function print_result(sd) { if (sd) { value_type = $sd->value_type; data = $sd->data + $key_len; + if (value_type == $LUA_TSTRING) { print(user_string(data)) + } else if (value_type == $LUA_TNUMBER) { print(user_long(data)) + } else if (value_type == $LUA_TBOOLEAN) { print(user_long(data)) + } else { - printf("bad value type found for key $key in shared_dict $zone\\n") + printf("bad value type found for key $key in shared_dict $dict\\n") } + } else { exit() } @@ -144,22 +151,26 @@ _EOC_ $print_result_func_def = <<_EOC_; function print_result(sd) { - printf("zone: \\"$zone\\" key: \\"$key\\"\\n") + printf("dict: \\"$dict\\" key: \\"$key\\"\\n") if (sd) { value_type = $sd->value_type; data = $sd->data + $key_len; if (value_type == $LUA_TSTRING) { printf("type: LUA_TSTRING\\n") printf("value: %s\\n", text_str(user_string(data))) + } else if (value_type == $LUA_TNUMBER) { printf("type: LUA_TNUMBER\\n") printf("value: %d\\n", user_long(data)) + } else if (value_type == $LUA_TBOOLEAN) { printf("type: LUA_TBOOLEAN\\n") printf("value: %d\\n", user_long(data)) + } else { - printf("ERROR: Bad value type found for key $key in shared_dict $zone\\n") + printf("ERROR: Bad value type found for key $key in shared_dict $dict\\n") } + } else { printf("ERROR: key not found\\n"); } @@ -178,8 +189,8 @@ $preamble function ngx_http_lua_shdict_lookup(zone, hash, key) { ctx = \@cast(zone, "ngx_shm_zone_t", "$nginx_path")->data sh = \@cast(ctx, "ngx_http_lua_shdict_ctx_t", "$nginx_path")->sh - node = \@cast(sh, "ngx_http_lua_shdict_shctx_t", "$nginx_path")->rbtree->root - sentinel = \@cast(sh, "ngx_http_lua_shdict_shctx_t", "$nginx_path")->rbtree->sentinel + node = $sh->rbtree->root + sentinel = $sh->rbtree->sentinel while (node != sentinel) { @@ -187,6 +198,7 @@ function ngx_http_lua_shdict_lookup(zone, hash, key) { node = $node->left continue } + if (hash > $node->key) { node = $node->right continue @@ -196,11 +208,14 @@ function ngx_http_lua_shdict_lookup(zone, hash, key) { data = $sd->data data_str = text_str(user_string(data)) data_key = substr(data_str, 0 , $key_len) + if (data_key == "$key"){ return sd + } else { if (data_key < "$key") { node = $node->left + } else { node = $node->right } @@ -221,25 +236,28 @@ probe process("$nginx_path").function("ngx_process_events_and_timers"), $set_timer_begin part = &\@var("ngx_cycle\@ngx_cycle.c")->shared_memory->part - zone = \@cast(part, "ngx_list_part_t")->elts + zone = $part->elts for (i = 0; ; i++) { - if (i >= \@cast(part, "ngx_list_part_t")->nelts) { - if (\@cast(part, "ngx_list_part_t")->next == 0) { + + if (i >= $part->nelts) { + if ($part->next == 0) { break } - part = \@cast(part, "ngx_list_part_t")->next - zone = \@cast(part, "ngx_list_part_t")->elts + part = $part->next + zone = $part->elts i = 0 } shm = &\@cast(zone, "ngx_shm_zone_t")[i]->shm name = &\@cast(shm, "ngx_shm_t")->name - if (\@cast(name, "ngx_str_t")->len != $zone_name_len) { + + if (\@cast(name, "ngx_str_t")->len != $dict_name_len) { continue; } - zone_name = user_string_n(\@cast(name, "ngx_str_t")->data, $zone_name_len) + + zone_name = user_string_n(\@cast(name, "ngx_str_t")->data, $dict_name_len) if (zone_name != $quoted_zone) { continue; } @@ -255,7 +273,6 @@ probe process("$nginx_path").function("ngx_process_events_and_timers"), printf("shm zone \\"%s\\" not found.\\n", $quoted_zone) } - $print_time_elasped_func_def exit() @@ -264,7 +281,6 @@ probe process("$nginx_path").function("ngx_process_events_and_timers"), } _EOC_ - if ($dump_src) { print $stap_src; exit; @@ -286,17 +302,16 @@ Options: -p Specify the nginx worker process pid. -a Pass extra arguments to the stap utility. -d Dump out the systemtap script source. - -n Specify the zone. - -k Specify the key. + --dict Specify the dict. + --key Specify the key. --raw Raw output. Examples: ngx-lua-shdict -p 12345 - ngx-lua-shdict -p 12345 -n dogs -k Jim + ngx-lua-shdict -p 12345 --dict dogs --key Jim _EOC_ } - sub quote_str { my $s = shift; $s =~ s/\\/\\\\/g; @@ -320,6 +335,7 @@ sub crc32 { for (my $j = 0; $j < 8; $j++) { if ($x & 1) { $x = ($x >> 1) ^ $polynomial; + } else { $x = $x >> 1; } From 41512fe1dd7fdfa066c05d76df2938f1014792c9 Mon Sep 17 00:00:00 2001 From: Guanlan Dai Date: Thu, 27 Jun 2013 17:57:16 -0700 Subject: [PATCH 04/15] modify n to dict and add some newline --- ngx-lua-shdict | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ngx-lua-shdict b/ngx-lua-shdict index ffaf0df..508b093 100755 --- a/ngx-lua-shdict +++ b/ngx-lua-shdict @@ -168,7 +168,7 @@ function print_result(sd) { printf("value: %d\\n", user_long(data)) } else { - printf("ERROR: Bad value type found for key $key in shared_dict $dict\\n") + error("ERROR: Bad value type found for key $key in shared_dict $dict\\n") } } else { @@ -187,6 +187,7 @@ $stap_src = <<_EOC_; $preamble function ngx_http_lua_shdict_lookup(zone, hash, key) { + error("ERROR: Bad value type found for key $key in shared_dict $dict\\n") ctx = \@cast(zone, "ngx_shm_zone_t", "$nginx_path")->data sh = \@cast(ctx, "ngx_http_lua_shdict_ctx_t", "$nginx_path")->sh node = $sh->rbtree->root From df5f553b78c647ae559e1971170947e3c0eed896 Mon Sep 17 00:00:00 2001 From: Guanlan Dai Date: Thu, 27 Jun 2013 17:59:07 -0700 Subject: [PATCH 05/15] change print to error --- ngx-lua-shdict | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ngx-lua-shdict b/ngx-lua-shdict index 508b093..dcb1f6b 100755 --- a/ngx-lua-shdict +++ b/ngx-lua-shdict @@ -168,7 +168,7 @@ function print_result(sd) { printf("value: %d\\n", user_long(data)) } else { - error("ERROR: Bad value type found for key $key in shared_dict $dict\\n") + error("Bad value type found for key $key in shared_dict $dict\\n") } } else { @@ -187,7 +187,6 @@ $stap_src = <<_EOC_; $preamble function ngx_http_lua_shdict_lookup(zone, hash, key) { - error("ERROR: Bad value type found for key $key in shared_dict $dict\\n") ctx = \@cast(zone, "ngx_shm_zone_t", "$nginx_path")->data sh = \@cast(ctx, "ngx_http_lua_shdict_ctx_t", "$nginx_path")->sh node = $sh->rbtree->root From 20b35d66608cd95f097f5878eec4a5c2f277db8f Mon Sep 17 00:00:00 2001 From: Guanlan Dai Date: Fri, 28 Jun 2013 15:11:50 -0700 Subject: [PATCH 06/15] add doc for shdict --- README.markdown | 16 ++++++++++++++++ ngx-lua-shdict | 3 ++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/README.markdown b/README.markdown index cfe3cf6..0bca898 100644 --- a/README.markdown +++ b/README.markdown @@ -1023,6 +1023,22 @@ Successfully tested on Linux kernel 3.7 and should work for other versions of ke This tool requires a Linux kernel compiled by gcc 4.5+ (preferrably gcc 4.7+) because gcc versions older than 4.5 generated incomplete DWARF debug info for C inlined functions. It is also recommended to enable DWARF format version 3 or above when compiling the kernel (by passing the `-gdwarf-3` or `-gdwarf-4` option to the `gcc` command line). +ngx-lua-shdict +------- + +This tool fetches the data from the shared memory dict by the specified dict and key. + + # assuming the nginx worker pid is 5050 + + $ ./ngx-shm -p 5050 --dict dogs --key Jim + Tracing 5050 (/opt/nginx/sbin/nginx)... + + dict: "dogs" key: "Jim" + type: LUA_TBOOLEAN + value: 1 + + 6 microseconds elapsed in the probe handler. + Community ========= diff --git a/ngx-lua-shdict b/ngx-lua-shdict index dcb1f6b..ba8ecc6 100755 --- a/ngx-lua-shdict +++ b/ngx-lua-shdict @@ -227,7 +227,8 @@ function ngx_http_lua_shdict_lookup(zone, hash, key) { $print_result_func_def probe process("$nginx_path").function("ngx_process_events_and_timers"), - process("$nginx_path").function("ngx_http_init_request") + process("$nginx_path").function("ngx_http_init_request")?, + process("$nginx_path").function("ngx_http_init_connection")? { if (pid() == target()) { From 7ee1e21c7d94cafb3169640d8070a30aca7859e1 Mon Sep 17 00:00:00 2001 From: Guanlan Dai Date: Mon, 1 Jul 2013 12:29:36 -0700 Subject: [PATCH 07/15] fix the output --- ngx-lua-shdict | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/ngx-lua-shdict b/ngx-lua-shdict index ba8ecc6..3957247 100755 --- a/ngx-lua-shdict +++ b/ngx-lua-shdict @@ -126,7 +126,7 @@ function print_result(sd) { print(user_long(data)) } else { - printf("bad value type found for key $key in shared_dict $dict\\n") + printf("ERROR: bad value type found for key $key in shared_dict $dict\\n") } } else { @@ -151,21 +151,35 @@ _EOC_ $print_result_func_def = <<_EOC_; function print_result(sd) { - printf("dict: \\"$dict\\" key: \\"$key\\"\\n") if (sd) { value_type = $sd->value_type; data = $sd->data + $key_len; if (value_type == $LUA_TSTRING) { printf("type: LUA_TSTRING\\n") printf("value: %s\\n", text_str(user_string(data))) + printf("expires: %d\\n", $sd->expires) + printf("flags: 0x%x\\n", $sd->user_flags) } else if (value_type == $LUA_TNUMBER) { printf("type: LUA_TNUMBER\\n") printf("value: %d\\n", user_long(data)) + printf("expires: %d\\n", $sd->expires) + printf("flags: 0x%x\\n", $sd->user_flags) } else if (value_type == $LUA_TBOOLEAN) { printf("type: LUA_TBOOLEAN\\n") - printf("value: %d\\n", user_long(data)) + if ( user_long(data) == 0) { + printf("value: false\\n") + + } else if ( user_long(data) == 1) { + printf("value: true\\n") + + } else { + printf("ERROR: value error\\n") + } + + printf("expires: %d\\n", $sd->expires) + printf("flags: 0x%x\\n", $sd->user_flags) } else { error("Bad value type found for key $key in shared_dict $dict\\n") @@ -227,8 +241,8 @@ function ngx_http_lua_shdict_lookup(zone, hash, key) { $print_result_func_def probe process("$nginx_path").function("ngx_process_events_and_timers"), - process("$nginx_path").function("ngx_http_init_request")?, - process("$nginx_path").function("ngx_http_init_connection")? + process("$nginx_path").function("ngx_http_init_request")!, + process("$nginx_path").function("ngx_http_init_connection") { if (pid() == target()) { From f60ff08cc12b0486c944c4cb5371756b1ad3dd64 Mon Sep 17 00:00:00 2001 From: Guanlan Dai Date: Mon, 1 Jul 2013 15:56:54 -0700 Subject: [PATCH 08/15] add some docs for lua-shdict --- README.markdown | 6 ++++-- ngx-lua-shdict | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/README.markdown b/README.markdown index 0bca898..460d2b4 100644 --- a/README.markdown +++ b/README.markdown @@ -1028,14 +1028,16 @@ ngx-lua-shdict This tool fetches the data from the shared memory dict by the specified dict and key. +Specify the `--raw` option when you need dump the raw value of the given key. + # assuming the nginx worker pid is 5050 - $ ./ngx-shm -p 5050 --dict dogs --key Jim + $ ./ngx-lua-shdict -p 5050 --dict dogs --key Jim Tracing 5050 (/opt/nginx/sbin/nginx)... dict: "dogs" key: "Jim" type: LUA_TBOOLEAN - value: 1 + value: true 6 microseconds elapsed in the probe handler. diff --git a/ngx-lua-shdict b/ngx-lua-shdict index 3957247..c477b4a 100755 --- a/ngx-lua-shdict +++ b/ngx-lua-shdict @@ -285,7 +285,7 @@ probe process("$nginx_path").function("ngx_process_events_and_timers"), } if (!zone_found) { - printf("shm zone \\"%s\\" not found.\\n", $quoted_zone) + printf("dict \\"%s\\" not found.\\n", $quoted_zone) } $print_time_elasped_func_def From 079707bc92ab3601b85b602d7cec973a1d49d867 Mon Sep 17 00:00:00 2001 From: Guanlan Dai Date: Mon, 1 Jul 2013 15:58:17 -0700 Subject: [PATCH 09/15] fix docs for lua-shdict --- README.markdown | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.markdown b/README.markdown index 460d2b4..53deb8a 100644 --- a/README.markdown +++ b/README.markdown @@ -1035,9 +1035,10 @@ Specify the `--raw` option when you need dump the raw value of the given key. $ ./ngx-lua-shdict -p 5050 --dict dogs --key Jim Tracing 5050 (/opt/nginx/sbin/nginx)... - dict: "dogs" key: "Jim" type: LUA_TBOOLEAN value: true + expires: 1372719243270 + flags: 0xa 6 microseconds elapsed in the probe handler. From 1423ed41edd5cd6a1a5e61a4970e9155880cb14d Mon Sep 17 00:00:00 2001 From: Guanlan Dai Date: Mon, 1 Jul 2013 16:03:47 -0700 Subject: [PATCH 10/15] lua-shdict: fix \t on doc --- README.markdown | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.markdown b/README.markdown index 53deb8a..41b67c5 100644 --- a/README.markdown +++ b/README.markdown @@ -1035,12 +1035,12 @@ Specify the `--raw` option when you need dump the raw value of the given key. $ ./ngx-lua-shdict -p 5050 --dict dogs --key Jim Tracing 5050 (/opt/nginx/sbin/nginx)... - type: LUA_TBOOLEAN - value: true - expires: 1372719243270 - flags: 0xa + type: LUA_TBOOLEAN + value: true + expires: 1372719243270 + flags: 0xa - 6 microseconds elapsed in the probe handler. + 6 microseconds elapsed in the probe handler. Community ========= From 1df4076b4d6a2756c257fa58ac0971baa4f5593a Mon Sep 17 00:00:00 2001 From: guanlan Date: Wed, 10 Jul 2013 11:20:33 -0700 Subject: [PATCH 11/15] feature: ngx-lua-shdict: add key write tracks --- ngx-lua-shdict | 220 +++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 187 insertions(+), 33 deletions(-) diff --git a/ngx-lua-shdict b/ngx-lua-shdict index c477b4a..8b9643b 100755 --- a/ngx-lua-shdict +++ b/ngx-lua-shdict @@ -12,6 +12,10 @@ use Getopt::Long qw( GetOptions ); GetOptions("a=s", \(my $stap_args), "d", \(my $dump_src), "h", \(my $help), + "lua51", \(my $lua51), + "luajit", \(my $luajit20), + "w", \(my $trace_write), + "f", \(my $find_value), "p=i", \(my $pid), "raw", \(my $raw), "dict=s", \(my $dict), @@ -62,6 +66,7 @@ if (!-f $nginx_file) { } my $nginx_path = readlink $nginx_file; +my $lua_path = get_lua_path(); my $ver = `stap --version 2>&1`; if (!defined $ver) { @@ -77,40 +82,121 @@ if ($ver =~ /version\s+(\d+\.\d+)/i) { } else { die "ERROR: unknown version of systemtap:\n$ver\n"; } +if (!$key) { + die "ERROR: please specify a key\n"; +} + +my $stap_src; +my $preamble; -if (!$dict) { - die "ERROR: please specify a dict zone\n"; +if ($trace_write) { + my $o = qq{\@cast(o, "TValue", "$lua_path")}; + my $L = qq{\@cast(L, "lua_State", "$lua_path")}; + my $gcr = qq{\@cast(gcr, "GCRef", "$lua_path")}; + my $gcobj = qq{\@cast(gcobj, "GCobj", "$lua_path")}; + my $str = qq{\@cast(str, "GCstr", "$lua_path")}; + my $sizeof_TValue = qq{\&\@cast(0, "TValue", "$lua_path")[1]}; + my $sizeof_GCstr = qq{\&\@cast(0, "GCstr", "$lua_path")[1]}; + my $TL_TSTR = "4294967291"; + my $NGX_HTTP_LUA_SHDICT_ADD = '0x0001'; + my $NGX_HTTP_LUA_SHDICT_REPLACE = '0x0002'; + my $NGX_HTTP_LUA_SHDICT_SAFE_STORE = '0x0004'; + my $LJ_TISNUM = '0xfffeffffu'; + $preamble = <<_EOC_; +probe begin { + printf("Tracing %d ($nginx_path)...\\n\\n", target()) + printf("Hit Ctrl-C to end.\\n\\n") } +_EOC_ -if (!$key) { - die "ERROR: please specify a key\n"; + $stap_src = <<_EOC_; +$preamble + +function gcref(gcr) +{ + return $gcr->gcptr32 } -my $hash = crc32($key); -my $dict_name_len = length $dict; -my $key_len = length $key; -my $quoted_zone = quote_str($dict); -my $LUA_TBOOLEAN = 1; -my $LUA_TNUMBER = 3; -my $LUA_TSTRING = 4; -my $part = qq{\@cast(part, "ngx_list_part_t")}; -my $node = qq{\@cast(node, "ngx_rbtree_node_t", "$nginx_path")}; -my $sd = qq{\@cast(sd, "ngx_http_lua_shdict_node_t", "$nginx_path")}; -my $sh = qq{\@cast(sh, "ngx_http_lua_shdict_shctx_t", "$nginx_path")}; +function gcval(o) +{ + return gcref(\&$o->gcr) +} -my $preamble; -my $print_result_func_def; -my $print_time_elasped_func_def; -my $set_timer_begin; +function strdata(s) +{ + return s + $sizeof_GCstr +} -if ($raw) { - $preamble = ""; +probe process("$nginx_path").function("ngx_http_lua_shdict_set_helper") +{ + if (pid() == target()) { + flags = \$flags + if (flags & $NGX_HTTP_LUA_SHDICT_ADD) { + op = "add" - $set_timer_begin = ""; + } else if (flags & $NGX_HTTP_LUA_SHDICT_REPLACE) { + op = "replace" - $print_time_elasped_func_def = ""; + } else { + op = "set" + } - $print_result_func_def = <<_EOC_; + if (flags & $NGX_HTTP_LUA_SHDICT_SAFE_STORE) { + op = "safe_" . op + } + + L = \$L + o = $L->base + $sizeof_TValue * (2 - 1) + if (o < $L->top && $o->it == $TL_TSTR) { + gcobj = gcval(o) + str = \&$gcobj->str + //printf("gmatch regex: %s\\n", user_string_n(strdata(str), $str->len)) + key = user_string_n(strdata(str), $str->len) + if (key == "$key") { + printf("%s %s", op, key) + + o = $L->base + $sizeof_TValue * (4 - 1) + if (o < $L->top) { + exptime = user_long(&$o->n) + printf(" exptime=%d", exptime) + } + + printf("\\n") + } + } + } +} +_EOC_ + +} else { + if (!$dict) { + die "ERROR: please specify a dict zone\n"; + } + + my $hash = crc32($key); + my $dict_name_len = length $dict; + my $key_len = length $key; + my $quoted_zone = quote_str($dict); + my $LUA_TBOOLEAN = 1; + my $LUA_TNUMBER = 3; + my $LUA_TSTRING = 4; + my $part = qq{\@cast(part, "ngx_list_part_t")}; + my $node = qq{\@cast(node, "ngx_rbtree_node_t", "$nginx_path")}; + my $sd = qq{\@cast(sd, "ngx_http_lua_shdict_node_t", "$nginx_path")}; + my $sh = qq{\@cast(sh, "ngx_http_lua_shdict_shctx_t", "$nginx_path")}; + + my $print_result_func_def; + my $print_time_elasped_func_def; + my $set_timer_begin; + + if ($raw) { + $preamble = ""; + + $set_timer_begin = ""; + + $print_time_elasped_func_def = ""; + + $print_result_func_def = <<_EOC_; function print_result(sd) { if (sd) { value_type = $sd->value_type; @@ -135,8 +221,8 @@ function print_result(sd) { } _EOC_ -} else { - $preamble = <<_EOC_; + } else { + $preamble = <<_EOC_; probe begin { printf("Tracing %d ($nginx_path)...\\n\\n", target()) } @@ -191,13 +277,10 @@ function print_result(sd) { } _EOC_ -} - -chop $preamble; - -my $stap_src; + } + chop $preamble; -$stap_src = <<_EOC_; + $stap_src = <<_EOC_; $preamble function ngx_http_lua_shdict_lookup(zone, hash, key) { @@ -296,6 +379,8 @@ probe process("$nginx_path").function("ngx_process_events_and_timers"), } _EOC_ +} + if ($dump_src) { print $stap_src; exit; @@ -317,13 +402,18 @@ Options: -p Specify the nginx worker process pid. -a Pass extra arguments to the stap utility. -d Dump out the systemtap script source. + -f Find value of specify key. + -w Trace writes to the dict. + --lua51 The target Nginx is using the standard Lua 5.1 interpreter. + --luajit The target Nginx is using the LuaJIT 2.0. --dict Specify the dict. --key Specify the key. --raw Raw output. Examples: ngx-lua-shdict -p 12345 - ngx-lua-shdict -p 12345 --dict dogs --key Jim + ngx-lua-shdict -p 12345 -f --dict dogs --key Jim --luajit + ngx-lua-shdict -p 12345 -w --key Jim --luajit _EOC_ } @@ -337,6 +427,70 @@ sub quote_str { return qq{"$s"}; } +sub get_lua_path { + my $lua_path; + + if (!defined $lua51 && !defined $luajit20) { + die "Neither --lua51 nor --luajit20 options are specified.\n"; + } + + my $maps_file = "/proc/$pid/maps"; + open my $in, $maps_file + or die "Cannot open $maps_file for reading: $!\n"; + + while (<$in>) { + if (m{\S+\bliblua-(\d+\.\d+)\.so(?:\.\d+)*$}) { + my ($path, $ver) = ($&, $1); + + if ($luajit20) { + die "The --luajit20 option is specified but seen standard Lua library: $path\n"; + } + + if ($ver ne '5.1') { + die "Nginx server $pid uses a Lua $ver library ", + "but only Lua 5.1 is supported.\n"; + } + + $lua_path = $path; + last; + + } elsif (m{\S+\bliblua\.so(?:\.\d+)*$}) { + my $path = $&; + + if ($luajit20) { + die "The --luajit20 option is specified but seen standard Lua library: $path\n"; + } + + $lua_path = $path; + last; + + } elsif (m{\S+\blibluajit-(\d+\.\d+)\.so(?:\.\d+)*$}) { + my ($path, $ver) = ($&, $1); + + if ($lua51) { + die "The --lua51 option is specified but seen the LuaJIT library: $path\n"; + } + + if ($ver ne '5.1') { + die "Nginx server $pid uses a Lua $ver compatible LuaJIT library ", + "but only Lua 5.1 is supported.\n"; + } + + $lua_path = $path; + last; + } + } + + close $in; + + if (!defined $lua_path) { + #warn "FALL BACK TO NGINX PATH"; + $lua_path = $nginx_path; + } + + return $lua_path; +} + sub crc32 { my ($input, $init_value, $polynomial) = @_; From b58c6d4b62b22e2a810d9a299cbb8489f91711c7 Mon Sep 17 00:00:00 2001 From: Guanlan Dai Date: Mon, 15 Jul 2013 16:14:27 -0700 Subject: [PATCH 12/15] ngx-lua-shdict: add a raw example --- ngx-lua-shdict | 1 + 1 file changed, 1 insertion(+) diff --git a/ngx-lua-shdict b/ngx-lua-shdict index 8b9643b..0140d62 100755 --- a/ngx-lua-shdict +++ b/ngx-lua-shdict @@ -413,6 +413,7 @@ Options: Examples: ngx-lua-shdict -p 12345 ngx-lua-shdict -p 12345 -f --dict dogs --key Jim --luajit + ngx-lua-shdict -p 12345 -f --dict dogs --key Jim --luajit --raw ngx-lua-shdict -p 12345 -w --key Jim --luajit _EOC_ } From 451624eec61b94459872708860a0644942fcae28 Mon Sep 17 00:00:00 2001 From: Guanlan Dai Date: Fri, 19 Jul 2013 11:00:42 -0700 Subject: [PATCH 13/15] docs: ngx-lua-shdict: update the docs. --- README.markdown | 22 ++++++++++++++++++++-- ngx-lua-shdict | 8 ++++---- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/README.markdown b/README.markdown index 41b67c5..bcdbb64 100644 --- a/README.markdown +++ b/README.markdown @@ -1026,13 +1026,21 @@ This tool requires a Linux kernel compiled by gcc 4.5+ (preferrably gcc 4.7+) be ngx-lua-shdict ------- -This tool fetches the data from the shared memory dict by the specified dict and key. +This tool analyzes shared memory dict and tracks dict operations in the specified running nginx process. +You can specify the `-f` option to fetches the data from the shared memory dict by the specified dict and key. Specify the `--raw` option when you need dump the raw value of the given key. +Similarly, you can specify the `-w` option to track dict writing: + +Specify the `--lua51` option when you're using the standard Lua 5.1 interpreter in your Nginx build, or `--luajit20` if LuaJIT 2.0 is used instead. Currently only LuaJIT is supported. + +Here's a sample command: + +Fetches the data from the shared memory dict # assuming the nginx worker pid is 5050 - $ ./ngx-lua-shdict -p 5050 --dict dogs --key Jim + $ ./ngx-lua-shdict -p 5050 -f --dict dogs --key Jim --luajit20 Tracing 5050 (/opt/nginx/sbin/nginx)... type: LUA_TBOOLEAN @@ -1042,6 +1050,16 @@ Specify the `--raw` option when you need dump the raw value of the given key. 6 microseconds elapsed in the probe handler. +Traces writes to the dict. + $./ngx-lua-shdict -p 5050 -w --key Jim --luajit20 + Tracing 5050 (/opt/nginx/sbin/nginx)... + + Hit Ctrl-C to end + + set Jim exptime=4626322717216342016 + replace Jim exptime=4626322717216342016 + ^C + Community ========= diff --git a/ngx-lua-shdict b/ngx-lua-shdict index 0140d62..14efe2b 100755 --- a/ngx-lua-shdict +++ b/ngx-lua-shdict @@ -13,7 +13,7 @@ GetOptions("a=s", \(my $stap_args), "d", \(my $dump_src), "h", \(my $help), "lua51", \(my $lua51), - "luajit", \(my $luajit20), + "luajit20", \(my $luajit20), "w", \(my $trace_write), "f", \(my $find_value), "p=i", \(my $pid), @@ -405,15 +405,15 @@ Options: -f Find value of specify key. -w Trace writes to the dict. --lua51 The target Nginx is using the standard Lua 5.1 interpreter. - --luajit The target Nginx is using the LuaJIT 2.0. + --luajit20 The target Nginx is using the LuaJIT 2.0. --dict Specify the dict. --key Specify the key. --raw Raw output. Examples: ngx-lua-shdict -p 12345 - ngx-lua-shdict -p 12345 -f --dict dogs --key Jim --luajit - ngx-lua-shdict -p 12345 -f --dict dogs --key Jim --luajit --raw + ngx-lua-shdict -p 12345 -f --dict dogs --key Jim --luajit20 + ngx-lua-shdict -p 12345 -f --dict dogs --key Jim --luajit20 --raw ngx-lua-shdict -p 12345 -w --key Jim --luajit _EOC_ } From 107df063bc0e5852d8b8e1fd2332c9e53751f85c Mon Sep 17 00:00:00 2001 From: Guanlan Dai Date: Fri, 19 Jul 2013 11:03:27 -0700 Subject: [PATCH 14/15] docs: ngx-lua-shdict: update the docs and format. --- README.markdown | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.markdown b/README.markdown index bcdbb64..f778205 100644 --- a/README.markdown +++ b/README.markdown @@ -1037,9 +1037,9 @@ Specify the `--lua51` option when you're using the standard Lua 5.1 interpreter Here's a sample command: -Fetches the data from the shared memory dict - # assuming the nginx worker pid is 5050 +Fetches the data from the shared memory dict: + # assuming the nginx worker pid is 5050 $ ./ngx-lua-shdict -p 5050 -f --dict dogs --key Jim --luajit20 Tracing 5050 (/opt/nginx/sbin/nginx)... @@ -1050,7 +1050,8 @@ Fetches the data from the shared memory dict 6 microseconds elapsed in the probe handler. -Traces writes to the dict. +Traces writes to the dict: + $./ngx-lua-shdict -p 5050 -w --key Jim --luajit20 Tracing 5050 (/opt/nginx/sbin/nginx)... From 906f7803c521008f7193ac4aca6362e6dda64ba7 Mon Sep 17 00:00:00 2001 From: Guanlan Dai Date: Mon, 5 Aug 2013 11:30:44 -0700 Subject: [PATCH 15/15] shdict: minor docs fix --- README.markdown | 6 ++++-- ngx-lua-shdict | 3 +++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/README.markdown b/README.markdown index 4f83c2a..4355348 100644 --- a/README.markdown +++ b/README.markdown @@ -1028,7 +1028,7 @@ ngx-lua-shdict This tool analyzes shared memory dict and tracks dict operations in the specified running nginx process. -You can specify the `-f` option to fetches the data from the shared memory dict by the specified dict and key. +You can specify the `-f` option to fetch the data from the shared memory dict name by the specified dict and key. Specify the `--raw` option when you need dump the raw value of the given key. Specify the `--lua51` option when you're using the standard Lua 5.1 interpreter in your Nginx build, or `--luajit20` if LuaJIT 2.0 is used instead. Currently only LuaJIT is supported. @@ -1046,7 +1046,7 @@ Here's a sample command to fetch the data from the shared memory dict: 6 microseconds elapsed in the probe handler. -Similarly, you can specify the `-w` option to track dict writing: +Similarly, you can specify the `-w` option to track dict writes for the given key: $./ngx-lua-shdict -p 5050 -w --key Jim --luajit20 Tracing 5050 (/opt/nginx/sbin/nginx)... @@ -1057,6 +1057,8 @@ Similarly, you can specify the `-w` option to track dict writing: replace Jim exptime=4626322717216342016 ^C +If you don't specify `-f` or `-w`, this tool will fetch the data by default. + ngx-lua-conn-pools ---------------- diff --git a/ngx-lua-shdict b/ngx-lua-shdict index 14efe2b..0253b98 100755 --- a/ngx-lua-shdict +++ b/ngx-lua-shdict @@ -90,6 +90,9 @@ my $stap_src; my $preamble; if ($trace_write) { + if ($dict) { + die "ERROR: specify a dict when tracing writes is not supported\n"; + } my $o = qq{\@cast(o, "TValue", "$lua_path")}; my $L = qq{\@cast(L, "lua_State", "$lua_path")}; my $gcr = qq{\@cast(gcr, "GCRef", "$lua_path")};