Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

OS-1723 DTrace should speak JSON

Reviewed by: Bryan Cantrill <bmc@joyent.com>
  • Loading branch information...
commit 8017f1f8eea31bd1160b5e50755242a2a9aabc7d 1 parent ced3e32
Joshua M. Clulow jclulow authored

Showing 21 changed files with 1,414 additions and 5 deletions. Show diff stats Hide diff stats

  1. +13 0 usr/src/cmd/dtrace/test/tst/common/Makefile
  2. +3 0  usr/src/cmd/dtrace/test/tst/common/aggs/tst.subr.d
  3. +179 0 usr/src/cmd/dtrace/test/tst/common/json/tst.general.d
  4. +218 0 usr/src/cmd/dtrace/test/tst/common/json/tst.general.d.out
  5. +51 0 usr/src/cmd/dtrace/test/tst/common/json/tst.strsize.d
  6. +13 0 usr/src/cmd/dtrace/test/tst/common/json/tst.strsize.d.out
  7. +61 0 usr/src/cmd/dtrace/test/tst/common/json/tst.usdt.c
  8. +65 0 usr/src/cmd/dtrace/test/tst/common/json/tst.usdt.d
  9. +11 0 usr/src/cmd/dtrace/test/tst/common/json/tst.usdt.d.out
  10. +27 0 usr/src/cmd/dtrace/test/tst/common/json/usdt.d
  11. +7 2 usr/src/cmd/dtrace/test/tst/common/privs/tst.func_access.ksh
  12. +35 0 usr/src/cmd/dtrace/test/tst/common/strtoll/err.BaseTooLarge.d
  13. +34 0 usr/src/cmd/dtrace/test/tst/common/strtoll/err.BaseTooSmall.d
  14. +66 0 usr/src/cmd/dtrace/test/tst/common/strtoll/tst.strtoll.d
  15. +20 0 usr/src/cmd/dtrace/test/tst/common/strtoll/tst.strtoll.d.out
  16. +4 0 usr/src/common/util/strtolctype.h
  17. +8 2 usr/src/lib/libdtrace/common/dt_open.c
  18. +593 0 usr/src/uts/common/dtrace/dtrace.c
  19. +3 1 usr/src/uts/common/sys/dtrace.h
  20. +2 0  usr/src/uts/intel/dtrace/Makefile
  21. +1 0  usr/src/uts/sparc/dtrace/Makefile
13 usr/src/cmd/dtrace/test/tst/common/Makefile
@@ -26,6 +26,7 @@
26 26
27 27 #
28 28 # Copyright (c) 2012 by Delphix. All rights reserved.
  29 +# Copyright (c) 2012, Joyent, Inc. All rights reserved.
29 30 #
30 31
31 32 include $(SRC)/Makefile.master
@@ -71,6 +72,18 @@ pid/tst.gcc.exe: pid/tst.gcc.c
71 72 $(GCC) -o pid/tst.gcc.exe pid/tst.gcc.c $(LDFLAGS)
72 73 $(POST_PROCESS) ; $(STRIP_STABS)
73 74
  75 +json/tst.usdt.o: json/usdt.h
  76 +
  77 +json/usdt.h: json/usdt.d
  78 + $(DTRACE) -h -s json/usdt.d -o json/usdt.h
  79 +
  80 +json/usdt.o: json/usdt.d json/tst.usdt.o
  81 + $(COMPILE.d) -o json/usdt.o -s json/usdt.d json/tst.usdt.o
  82 +
  83 +json/tst.usdt.exe: json/tst.usdt.o json/usdt.o
  84 + $(LINK.c) -o json/tst.usdt.exe json/tst.usdt.o json/usdt.o $(LDLIBS)
  85 + $(POST_PROCESS) ; $(STRIP_STABS)
  86 +
74 87 usdt/tst.args.exe: usdt/tst.args.o usdt/args.o
75 88 $(LINK.c) -o usdt/tst.args.exe usdt/tst.args.o usdt/args.o $(LDLIBS)
76 89 $(POST_PROCESS) ; $(STRIP_STABS)
3  usr/src/cmd/dtrace/test/tst/common/aggs/tst.subr.d
@@ -22,6 +22,7 @@
22 22 /*
23 23 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
24 24 * Use is subject to license terms.
  25 + * Copyright (c) 2012, Joyent, Inc. All rights reserved.
25 26 */
26 27
27 28 #include <sys/dtrace.h>
@@ -99,6 +100,8 @@ STRFUNC(inet_ntop(AF_INET, (void *)alloca(sizeof (ipaddr_t))))
99 100 STRFUNC(toupper("foo"))
100 101 STRFUNC(tolower("BAR"))
101 102 INTFUNC(getf(0))
  103 +INTFUNC(strtoll("0x12EE5D5", 16))
  104 +STRFUNC(json("{\"systemtap\": false}", "systemtap"))
102 105
103 106 BEGIN
104 107 /subr == DIF_SUBR_MAX + 1/
179 usr/src/cmd/dtrace/test/tst/common/json/tst.general.d
... ... @@ -0,0 +1,179 @@
  1 +/*
  2 + * This file and its contents are supplied under the terms of the
  3 + * Common Development and Distribution License ("CDDL"), version 1.0.
  4 + * You may only use this file in accordance with the terms of version
  5 + * 1.0 of the CDDL.
  6 + *
  7 + * A full copy of the text of the CDDL should have accompanied this
  8 + * source. A copy of the CDDL is also available via the Internet at
  9 + * http://www.illumos.org/license/CDDL.
  10 + */
  11 +
  12 +/*
  13 + * Copyright 2012, Joyent, Inc. All rights reserved.
  14 + */
  15 +
  16 +/*
  17 + * General functional tests of JSON parser for json().
  18 + */
  19 +
  20 +#pragma D option quiet
  21 +#pragma D option strsize=1k
  22 +
  23 +#define TST(name) \
  24 + printf("\ntst |%s|\n", name)
  25 +#define IN2(vala, valb) \
  26 + in = strjoin(vala, valb); \
  27 + printf("in |%s|\n", in)
  28 +#define IN(val) \
  29 + in = val; \
  30 + printf("in |%s|\n", in)
  31 +#define SEL(ss) \
  32 + out = json(in, ss); \
  33 + printf("sel |%s|\nout |%s|\n", ss, \
  34 + out != NULL ? out : "<NULL>")
  35 +
  36 +BEGIN
  37 +{
  38 + TST("empty array");
  39 + IN("[]");
  40 + SEL("0");
  41 +
  42 + TST("one-element array: integer");
  43 + IN("[1]");
  44 + SEL("0");
  45 + SEL("1");
  46 + SEL("100");
  47 + SEL("-1");
  48 +
  49 + TST("one-element array: hex integer (not in spec, not supported)");
  50 + IN("[0x1000]");
  51 + SEL("0");
  52 +
  53 + TST("one-element array: float");
  54 + IN("[1.5001]");
  55 + SEL("0");
  56 +
  57 + TST("one-element array: float + exponent");
  58 + IN("[16.3e10]");
  59 + SEL("0");
  60 +
  61 + TST("one-element array: integer + whitespace");
  62 + IN("[ \t 5\t]");
  63 + SEL("0");
  64 +
  65 + TST("one-element array: integer + exponent + whitespace");
  66 + IN("[ \t \t 16E10 \t ]");
  67 + SEL("0");
  68 +
  69 + TST("one-element array: string");
  70 + IN("[\"alpha\"]");
  71 + SEL("0");
  72 +
  73 + TST("alternative first-element indexing");
  74 + IN("[1,5,10,15,20]");
  75 + SEL("[0]");
  76 + SEL("[3]");
  77 + SEL("[4]");
  78 + SEL("[5]");
  79 +
  80 + TST("one-element array: object");
  81 + IN("[ { \"first\": true, \"second\": false }]");
  82 + SEL("0.first");
  83 + SEL("0.second");
  84 + SEL("0.third");
  85 +
  86 + TST("many-element array: integers");
  87 + IN("[0,1,1,2,3,5,8,13,21,34,55,89,144,233,377]");
  88 + SEL("10"); /* F(10) = 55 */
  89 + SEL("14"); /* F(14) = 377 */
  90 + SEL("19");
  91 +
  92 + TST("many-element array: multiple types");
  93 + IN2("[\"string\",32,true,{\"a\":9,\"b\":false},100.3e10,false,200.5,",
  94 + "{\"key\":\"val\"},null]");
  95 + SEL("0");
  96 + SEL("0.notobject");
  97 + SEL("1");
  98 + SEL("2");
  99 + SEL("3");
  100 + SEL("3.a");
  101 + SEL("3.b");
  102 + SEL("3.c");
  103 + SEL("4");
  104 + SEL("5");
  105 + SEL("6");
  106 + SEL("7");
  107 + SEL("7.key");
  108 + SEL("7.key.notobject");
  109 + SEL("7.nonexist");
  110 + SEL("8");
  111 + SEL("9");
  112 +
  113 + TST("many-element array: multiple types + whitespace");
  114 + IN2("\n[\t\"string\" ,\t32 , true\t,\t {\"a\": 9,\t\"b\": false},\t\t",
  115 + "100.3e10, false, 200.5,{\"key\" \t:\n \"val\"},\t\t null ]\t\t");
  116 + SEL("0");
  117 + SEL("0.notobject");
  118 + SEL("1");
  119 + SEL("2");
  120 + SEL("3");
  121 + SEL("3.a");
  122 + SEL("3.b");
  123 + SEL("3.c");
  124 + SEL("4");
  125 + SEL("5");
  126 + SEL("6");
  127 + SEL("7");
  128 + SEL("7.key");
  129 + SEL("7.key.notobject");
  130 + SEL("7.nonexist");
  131 + SEL("8");
  132 + SEL("9");
  133 +
  134 + TST("two-element array: various string escape codes");
  135 + IN2("[\"abcd \\\" \\\\ \\/ \\b \\f \\n \\r \\t \\u0000 \\uf00F \", ",
  136 + "\"final\"]");
  137 + SEL("0");
  138 + SEL("1");
  139 +
  140 + TST("three-element array: broken escape code");
  141 + IN("[\"fine here\", \"dodgey \\u00AZ\", \"wont get here\"]");
  142 + SEL("0");
  143 + SEL("1");
  144 + SEL("2");
  145 +
  146 + TST("nested objects");
  147 + IN2("{ \"top\": { \"mid\" : { \"legs\": \"feet\" }, \"number\": 9, ",
  148 + "\"array\":[0,1,{\"a\":true,\"bb\":[1,2,false,{\"x\":\"yz\"}]}]}}");
  149 + SEL("top");
  150 + SEL("fargo");
  151 + SEL("top.mid");
  152 + SEL("top.centre");
  153 + SEL("top.mid.legs");
  154 + SEL("top.mid.number");
  155 + SEL("top.mid.array");
  156 + SEL("top.number");
  157 + SEL("top.array");
  158 + SEL("top.array[0]");
  159 + SEL("top.array[1]");
  160 + SEL("top.array[2]");
  161 + SEL("top.array[2].a");
  162 + SEL("top.array[2].b");
  163 + SEL("top.array[2].bb");
  164 + SEL("top.array[2].bb[0]");
  165 + SEL("top.array[2].bb[1]");
  166 + SEL("top.array[2].bb[2]");
  167 + SEL("top.array[2].bb[3]");
  168 + SEL("top.array[2].bb[3].x");
  169 + SEL("top.array[2].bb[3].x.nofurther");
  170 + SEL("top.array[2].bb[4]");
  171 + SEL("top.array[3]");
  172 +
  173 + exit(0);
  174 +}
  175 +
  176 +ERROR
  177 +{
  178 + exit(1);
  179 +}
218 usr/src/cmd/dtrace/test/tst/common/json/tst.general.d.out
... ... @@ -0,0 +1,218 @@
  1 +
  2 +tst |empty array|
  3 +in |[]|
  4 +sel |0|
  5 +out |<NULL>|
  6 +
  7 +tst |one-element array: integer|
  8 +in |[1]|
  9 +sel |0|
  10 +out |1|
  11 +sel |1|
  12 +out |<NULL>|
  13 +sel |100|
  14 +out |<NULL>|
  15 +sel |-1|
  16 +out |<NULL>|
  17 +
  18 +tst |one-element array: hex integer (not in spec, not supported)|
  19 +in |[0x1000]|
  20 +sel |0|
  21 +out |<NULL>|
  22 +
  23 +tst |one-element array: float|
  24 +in |[1.5001]|
  25 +sel |0|
  26 +out |1.5001|
  27 +
  28 +tst |one-element array: float + exponent|
  29 +in |[16.3e10]|
  30 +sel |0|
  31 +out |16.3e10|
  32 +
  33 +tst |one-element array: integer + whitespace|
  34 +in |[ 5 ]|
  35 +sel |0|
  36 +out |5|
  37 +
  38 +tst |one-element array: integer + exponent + whitespace|
  39 +in |[ 16E10 ]|
  40 +sel |0|
  41 +out |16E10|
  42 +
  43 +tst |one-element array: string|
  44 +in |["alpha"]|
  45 +sel |0|
  46 +out |alpha|
  47 +
  48 +tst |alternative first-element indexing|
  49 +in |[1,5,10,15,20]|
  50 +sel |[0]|
  51 +out |1|
  52 +sel |[3]|
  53 +out |15|
  54 +sel |[4]|
  55 +out |20|
  56 +sel |[5]|
  57 +out |<NULL>|
  58 +
  59 +tst |one-element array: object|
  60 +in |[ { "first": true, "second": false }]|
  61 +sel |0.first|
  62 +out |true|
  63 +sel |0.second|
  64 +out |false|
  65 +sel |0.third|
  66 +out |<NULL>|
  67 +
  68 +tst |many-element array: integers|
  69 +in |[0,1,1,2,3,5,8,13,21,34,55,89,144,233,377]|
  70 +sel |10|
  71 +out |55|
  72 +sel |14|
  73 +out |377|
  74 +sel |19|
  75 +out |<NULL>|
  76 +
  77 +tst |many-element array: multiple types|
  78 +in |["string",32,true,{"a":9,"b":false},100.3e10,false,200.5,{"key":"val"},null]|
  79 +sel |0|
  80 +out |string|
  81 +sel |0.notobject|
  82 +out |<NULL>|
  83 +sel |1|
  84 +out |32|
  85 +sel |2|
  86 +out |true|
  87 +sel |3|
  88 +out |{"a":9,"b":false}|
  89 +sel |3.a|
  90 +out |9|
  91 +sel |3.b|
  92 +out |false|
  93 +sel |3.c|
  94 +out |<NULL>|
  95 +sel |4|
  96 +out |100.3e10|
  97 +sel |5|
  98 +out |false|
  99 +sel |6|
  100 +out |200.5|
  101 +sel |7|
  102 +out |{"key":"val"}|
  103 +sel |7.key|
  104 +out |val|
  105 +sel |7.key.notobject|
  106 +out |<NULL>|
  107 +sel |7.nonexist|
  108 +out |<NULL>|
  109 +sel |8|
  110 +out |null|
  111 +sel |9|
  112 +out |<NULL>|
  113 +
  114 +tst |many-element array: multiple types + whitespace|
  115 +in |
  116 +[ "string" , 32 , true , {"a": 9, "b": false}, 100.3e10, false, 200.5,{"key" :
  117 + "val"}, null ] |
  118 +sel |0|
  119 +out |string|
  120 +sel |0.notobject|
  121 +out |<NULL>|
  122 +sel |1|
  123 +out |32|
  124 +sel |2|
  125 +out |true|
  126 +sel |3|
  127 +out |{"a": 9, "b": false}|
  128 +sel |3.a|
  129 +out |9|
  130 +sel |3.b|
  131 +out |false|
  132 +sel |3.c|
  133 +out |<NULL>|
  134 +sel |4|
  135 +out |100.3e10|
  136 +sel |5|
  137 +out |false|
  138 +sel |6|
  139 +out |200.5|
  140 +sel |7|
  141 +out |{"key" :
  142 + "val"}|
  143 +sel |7.key|
  144 +out |val|
  145 +sel |7.key.notobject|
  146 +out |<NULL>|
  147 +sel |7.nonexist|
  148 +out |<NULL>|
  149 +sel |8|
  150 +out |null|
  151 +sel |9|
  152 +out |<NULL>|
  153 +
  154 +tst |two-element array: various string escape codes|
  155 +in |["abcd \" \\ \/ \b \f \n \r \t \u0000 \uf00F ", "final"]|
  156 +sel |0|
  157 +out |abcd \" \\ \/ \b \f \n \r \t \u0000 \uf00F |
  158 +sel |1|
  159 +out |final|
  160 +
  161 +tst |three-element array: broken escape code|
  162 +in |["fine here", "dodgey \u00AZ", "wont get here"]|
  163 +sel |0|
  164 +out |fine here|
  165 +sel |1|
  166 +out |<NULL>|
  167 +sel |2|
  168 +out |<NULL>|
  169 +
  170 +tst |nested objects|
  171 +in |{ "top": { "mid" : { "legs": "feet" }, "number": 9, "array":[0,1,{"a":true,"bb":[1,2,false,{"x":"yz"}]}]}}|
  172 +sel |top|
  173 +out |{ "mid" : { "legs": "feet" }, "number": 9, "array":[0,1,{"a":true,"bb":[1,2,false,{"x":"yz"}]}]}|
  174 +sel |fargo|
  175 +out |<NULL>|
  176 +sel |top.mid|
  177 +out |{ "legs": "feet" }|
  178 +sel |top.centre|
  179 +out |<NULL>|
  180 +sel |top.mid.legs|
  181 +out |feet|
  182 +sel |top.mid.number|
  183 +out |<NULL>|
  184 +sel |top.mid.array|
  185 +out |<NULL>|
  186 +sel |top.number|
  187 +out |9|
  188 +sel |top.array|
  189 +out |[0,1,{"a":true,"bb":[1,2,false,{"x":"yz"}]}]|
  190 +sel |top.array[0]|
  191 +out |0|
  192 +sel |top.array[1]|
  193 +out |1|
  194 +sel |top.array[2]|
  195 +out |{"a":true,"bb":[1,2,false,{"x":"yz"}]}|
  196 +sel |top.array[2].a|
  197 +out |true|
  198 +sel |top.array[2].b|
  199 +out |<NULL>|
  200 +sel |top.array[2].bb|
  201 +out |[1,2,false,{"x":"yz"}]|
  202 +sel |top.array[2].bb[0]|
  203 +out |1|
  204 +sel |top.array[2].bb[1]|
  205 +out |2|
  206 +sel |top.array[2].bb[2]|
  207 +out |false|
  208 +sel |top.array[2].bb[3]|
  209 +out |{"x":"yz"}|
  210 +sel |top.array[2].bb[3].x|
  211 +out |yz|
  212 +sel |top.array[2].bb[3].x.nofurther|
  213 +out |<NULL>|
  214 +sel |top.array[2].bb[4]|
  215 +out |<NULL>|
  216 +sel |top.array[3]|
  217 +out |<NULL>|
  218 +
51 usr/src/cmd/dtrace/test/tst/common/json/tst.strsize.d
... ... @@ -0,0 +1,51 @@
  1 +/*
  2 + * This file and its contents are supplied under the terms of the
  3 + * Common Development and Distribution License ("CDDL"), version 1.0.
  4 + * You may only use this file in accordance with the terms of version
  5 + * 1.0 of the CDDL.
  6 + *
  7 + * A full copy of the text of the CDDL should have accompanied this
  8 + * source. A copy of the CDDL is also available via the Internet at
  9 + * http://www.illumos.org/license/CDDL.
  10 + */
  11 +
  12 +/*
  13 + * Copyright 2012, Joyent, Inc. All rights reserved.
  14 + */
  15 +
  16 +/*
  17 + * ASSERTION:
  18 + * json() run time must be bounded above by strsize. This test makes strsize
  19 + * small and deliberately overflows it to prove we bail and return NULL in
  20 + * the event that we run off the end of the string.
  21 + *
  22 + */
  23 +
  24 +#pragma D option quiet
  25 +#pragma D option strsize=18
  26 +
  27 +BEGIN
  28 +{
  29 + in = "{\"a\": 1024}"; /* length == 19 */
  30 + out = json(in, "a");
  31 + printf("|%s|\n%s\n\n", in, out != NULL ? out : "<NULL>");
  32 +
  33 + in = "{\"a\": 1024}"; /* length == 11 */
  34 + out = json(in, "a");
  35 + printf("|%s|\n%s\n\n", in, out != NULL ? out : "<NULL>");
  36 +
  37 + in = "{\"a\":false,\"b\":true}"; /* length == 20 */
  38 + out = json(in, "b");
  39 + printf("|%s|\n%s\n\n", in, out != NULL ? out : "<NULL>");
  40 +
  41 + in = "{\"a\":false,\"b\":20}"; /* length == 18 */
  42 + out = json(in, "b");
  43 + printf("|%s|\n%s\n\n", in, out != NULL ? out : "<NULL>");
  44 +
  45 + exit(0);
  46 +}
  47 +
  48 +ERROR
  49 +{
  50 + exit(1);
  51 +}
13 usr/src/cmd/dtrace/test/tst/common/json/tst.strsize.d.out
... ... @@ -0,0 +1,13 @@
  1 +|{"a": 1024|
  2 +<NULL>
  3 +
  4 +|{"a": 1024}|
  5 +1024
  6 +
  7 +|{"a":false,"b":tru|
  8 +<NULL>
  9 +
  10 +|{"a":false,"b":20}|
  11 +20
  12 +
  13 +
61 usr/src/cmd/dtrace/test/tst/common/json/tst.usdt.c
... ... @@ -0,0 +1,61 @@
  1 +/*
  2 + * This file and its contents are supplied under the terms of the
  3 + * Common Development and Distribution License ("CDDL"), version 1.0.
  4 + * You may only use this file in accordance with the terms of version
  5 + * 1.0 of the CDDL.
  6 + *
  7 + * A full copy of the text of the CDDL should have accompanied this
  8 + * source. A copy of the CDDL is also available via the Internet at
  9 + * http://www.illumos.org/license/CDDL.
  10 + */
  11 +
  12 +/*
  13 + * Copyright 2012 (c), Joyent, Inc. All rights reserved.
  14 + */
  15 +
  16 +#include <sys/sdt.h>
  17 +#include "usdt.h"
  18 +
  19 +#define FMT "{" \
  20 + " \"sizes\": [ \"first\", 2, %f ]," \
  21 + " \"index\": %d," \
  22 + " \"facts\": {" \
  23 + " \"odd\": \"%s\"," \
  24 + " \"even\": \"%s\"" \
  25 + " }," \
  26 + " \"action\": \"%s\"" \
  27 + "}\n"
  28 +
  29 +int
  30 +waiting(volatile int *a)
  31 +{
  32 + return (*a);
  33 +}
  34 +
  35 +int
  36 +main(int argc, char **argv)
  37 +{
  38 + volatile int a = 0;
  39 + int idx;
  40 + double size = 250.5;
  41 +
  42 + while (waiting(&a) == 0)
  43 + continue;
  44 +
  45 + for (idx = 0; idx < 10; idx++) {
  46 + char *odd, *even, *json, *action;
  47 +
  48 + size *= 1.78;
  49 + odd = idx % 2 == 1 ? "true" : "false";
  50 + even = idx % 2 == 0 ? "true" : "false";
  51 + action = idx == 7 ? "ignore" : "print";
  52 +
  53 + asprintf(&json, FMT, size, idx, odd, even, action);
  54 + BUNYAN_FAKE_LOG_DEBUG(json);
  55 + free(json);
  56 + }
  57 +
  58 + BUNYAN_FAKE_LOG_DEBUG("{\"finished\": true}");
  59 +
  60 + return (0);
  61 +}
65 usr/src/cmd/dtrace/test/tst/common/json/tst.usdt.d
... ... @@ -0,0 +1,65 @@
  1 +/*
  2 + * This file and its contents are supplied under the terms of the
  3 + * Common Development and Distribution License ("CDDL"), version 1.0.
  4 + * You may only use this file in accordance with the terms of version
  5 + * 1.0 of the CDDL.
  6 + *
  7 + * A full copy of the text of the CDDL should have accompanied this
  8 + * source. A copy of the CDDL is also available via the Internet at
  9 + * http://www.illumos.org/license/CDDL.
  10 + */
  11 +
  12 +/*
  13 + * Copyright (c) 2012, Joyent, Inc. All rights reserved.
  14 + */
  15 +
  16 +#pragma D option strsize=4k
  17 +#pragma D option quiet
  18 +#pragma D option destructive
  19 +
  20 +/*
  21 + * This test reads a JSON string from a USDT probe, roughly simulating the
  22 + * primary motivating use case for the json() subroutine: filtering
  23 + * JSON-formatted log messages from a logging subsystem like node-bunyan.
  24 + */
  25 +
  26 +pid$1:a.out:waiting:entry
  27 +{
  28 + this->value = (int *)alloca(sizeof (int));
  29 + *this->value = 1;
  30 + copyout(this->value, arg0, sizeof (int));
  31 +}
  32 +
  33 +bunyan*$1:::log-*
  34 +{
  35 + this->j = copyinstr(arg0);
  36 +}
  37 +
  38 +bunyan*$1:::log-*
  39 +/json(this->j, "finished") == NULL && json(this->j, "action") != "ignore"/
  40 +{
  41 + this->index = strtoll(json(this->j, "index"));
  42 + this->size = json(this->j, "sizes[2]");
  43 + this->odd = json(this->j, "facts.odd");
  44 + this->even = json(this->j, "facts.even");
  45 + printf("[%d] sz %s odd %s even %s\n", this->index, this->size,
  46 + this->odd, this->even);
  47 +}
  48 +
  49 +bunyan*$1:::log-*
  50 +/json(this->j, "finished") != NULL/
  51 +{
  52 + printf("FINISHED!\n");
  53 + exit(0);
  54 +}
  55 +
  56 +tick-10s
  57 +{
  58 + printf("ERROR: Timed out before finish message!\n");
  59 + exit(1);
  60 +}
  61 +
  62 +ERROR
  63 +{
  64 + exit(1);
  65 +}
11 usr/src/cmd/dtrace/test/tst/common/json/tst.usdt.d.out
... ... @@ -0,0 +1,11 @@
  1 +[0] sz 445.890000 odd false even true
  2 +[1] sz 793.684200 odd true even false
  3 +[2] sz 1412.757876 odd false even true
  4 +[3] sz 2514.709019 odd true even false
  5 +[4] sz 4476.182054 odd false even true
  6 +[5] sz 7967.604057 odd true even false
  7 +[6] sz 14182.335221 odd false even true
  8 +[8] sz 44935.310914 odd false even true
  9 +[9] sz 79984.853427 odd true even false
  10 +FINISHED!
  11 +
27 usr/src/cmd/dtrace/test/tst/common/json/usdt.d
... ... @@ -0,0 +1,27 @@
  1 +/*
  2 + * This file and its contents are supplied under the terms of the
  3 + * Common Development and Distribution License ("CDDL"), version 1.0.
  4 + * You may only use this file in accordance with the terms of version
  5 + * 1.0 of the CDDL.
  6 + *
  7 + * A full copy of the text of the CDDL should have accompanied this
  8 + * source. A copy of the CDDL is also available via the Internet at
  9 + * http://www.illumos.org/license/CDDL.
  10 + */
  11 +
  12 +/*
  13 + * Copyright 2012, Joyent, Inc. All rights reserved.
  14 + */
  15 +
  16 +/*
  17 + * Sets up a fake node-bunyan-like USDT provider for use from C.
  18 + */
  19 +
  20 +provider bunyan_fake {
  21 + probe log__trace(char *msg);
  22 + probe log__debug(char *msg);
  23 + probe log__info(char *msg);
  24 + probe log__warn(char *msg);
  25 + probe log__error(char *msg);
  26 + probe log__fatal(char *msg);
  27 +};
9 usr/src/cmd/dtrace/test/tst/common/privs/tst.func_access.ksh
@@ -22,8 +22,8 @@
22 22 #
23 23 # Copyright 2006 Sun Microsystems, Inc. All rights reserved.
24 24 # Use is subject to license terms.
  25 +# Copyright (c) 2012, Joyent, Inc. All rights reserved.
25 26 #
26   -#ident "%Z%%M% %I% %E% SMI"
27 27
28 28 ppriv -s A=basic,dtrace_proc,dtrace_user $$
29 29
@@ -31,7 +31,7 @@ ppriv -s A=basic,dtrace_proc,dtrace_user $$
31 31
32 32 BEGIN {
33 33 errorcount = 0;
34   - expected_errorcount = 23;
  34 + expected_errorcount = 27;
35 35 }
36 36
37 37 BEGIN { trace(mutex_owned(&`pidlock)); }
@@ -55,6 +55,8 @@ BEGIN { trace(strtok(`initname, "/")); }
55 55 BEGIN { trace(strtok(NULL, "/")); }
56 56 BEGIN { trace(strtok("foo/bar", `initname)); }
57 57 BEGIN { trace(strtok(NULL, `initname)); }
  58 +BEGIN { trace(strtoll(`initname)); }
  59 +BEGIN { trace(strtoll(`initname, 10)); }
58 60 BEGIN { trace(substr(`initname, 2, 3)); }
59 61
60 62 BEGIN { trace(ddi_pathname(`top_devinfo, 1)); }
@@ -63,6 +65,9 @@ BEGIN { trace(strjoin("foo", `initname)); }
63 65 BEGIN { trace(dirname(`initname)); }
64 66 BEGIN { trace(cleanpath(`initname)); }
65 67
  68 +BEGIN { j = "{\"/sbin/init\":\"uh oh\"}"; trace(json(j, `initname)); }
  69 +BEGIN { trace(json(`initname, "x")); }
  70 +
66 71 ERROR {
67 72 errorcount++;
68 73 }
35 usr/src/cmd/dtrace/test/tst/common/strtoll/err.BaseTooLarge.d
... ... @@ -0,0 +1,35 @@
  1 +/*
  2 + * This file and its contents are supplied under the terms of the
  3 + * Common Development and Distribution License ("CDDL"), version 1.0.
  4 + * You may only use this file in accordance with the terms of version
  5 + * 1.0 of the CDDL.
  6 + *
  7 + * A full copy of the text of the CDDL should have accompanied this
  8 + * source. A copy of the CDDL is also available via the Internet at
  9 + * http://www.illumos.org/license/CDDL.
  10 + */
  11 +
  12 +/*
  13 + * Copyright (c) 2012, Joyent, Inc. All rights reserved.
  14 + */
  15 +
  16 +/*
  17 + * ASSERTION:
  18 + * The largest base we will accept is Base 36 -- i.e. using all of 0-9 and
  19 + * A-Z as numerals.
  20 + *
  21 + * SECTION: Actions and Subroutines/strtoll()
  22 + */
  23 +
  24 +#pragma D option quiet
  25 +
  26 +BEGIN
  27 +{
  28 + printf("%d\n", strtoll("0", 37));
  29 + exit(0);
  30 +}
  31 +
  32 +ERROR
  33 +{
  34 + exit(1);
  35 +}
34 usr/src/cmd/dtrace/test/tst/common/strtoll/err.BaseTooSmall.d
... ... @@ -0,0 +1,34 @@
  1 +/*
  2 + * This file and its contents are supplied under the terms of the
  3 + * Common Development and Distribution License ("CDDL"), version 1.0.
  4 + * You may only use this file in accordance with the terms of version
  5 + * 1.0 of the CDDL.
  6 + *
  7 + * A full copy of the text of the CDDL should have accompanied this
  8 + * source. A copy of the CDDL is also available via the Internet at
  9 + * http://www.illumos.org/license/CDDL.
  10 + */
  11 +
  12 +/*
  13 + * Copyright (c) 2012, Joyent, Inc. All rights reserved.
  14 + */
  15 +
  16 +/*
  17 + * ASSERTION:
  18 + * The smallest base we will accept is Base 2.
  19 + *
  20 + * SECTION: Actions and Subroutines/strtoll()
  21 + */
  22 +
  23 +#pragma D option quiet
  24 +
  25 +BEGIN
  26 +{
  27 + printf("%d\n", strtoll("0", 1));
  28 + exit(0);
  29 +}
  30 +
  31 +ERROR
  32 +{
  33 + exit(1);
  34 +}
66 usr/src/cmd/dtrace/test/tst/common/strtoll/tst.strtoll.d
... ... @@ -0,0 +1,66 @@
  1 +/*
  2 + * This file and its contents are supplied under the terms of the
  3 + * Common Development and Distribution License ("CDDL"), version 1.0.
  4 + * You may only use this file in accordance with the terms of version
  5 + * 1.0 of the CDDL.
  6 + *
  7 + * A full copy of the text of the CDDL should have accompanied this
  8 + * source. A copy of the CDDL is also available via the Internet at
  9 + * http://www.illumos.org/license/CDDL.
  10 + */
  11 +
  12 +/*
  13 + * Copyright (c) 2012, Joyent, Inc. All rights reserved.
  14 + */
  15 +
  16 +/*
  17 + * ASSERTION:
  18 + * Test the strtoll() subroutine.
  19 + *
  20 + * SECTION: Actions and Subroutines/strtoll()
  21 + */
  22 +
  23 +#pragma D option quiet
  24 +
  25 +BEGIN
  26 +{
  27 +
  28 + /* minimum base (2) and maximum base (36): */
  29 + printf("%d\n", strtoll("0", 2));
  30 + printf("%d\n", strtoll("1", 36));
  31 +
  32 + /* simple tests: */
  33 + printf("%d\n", strtoll("0x20", 16));
  34 + printf("%d\n", strtoll("-32", 10));
  35 + printf("%d\n", strtoll("010", 8));
  36 + printf("%d\n", strtoll("101010", 2));
  37 +
  38 + /* INT64_MIN and INT64_MAX: */
  39 + printf("%d\n", strtoll("9223372036854775807"));
  40 + printf("%d\n", strtoll("-9223372036854775808"));
  41 + printf("%d\n", strtoll("0777777777777777777777", 8));
  42 + printf("%d\n", strtoll("-01000000000000000000000", 8));
  43 +
  44 + /* wrapping: */
  45 + printf("%d\n", strtoll("1000000000000000000000", 8));
  46 + printf("%d\n", strtoll("-1000000000000000000001", 8));
  47 +
  48 + /* hex without prefix: */
  49 + printf("%d\n", strtoll("baddcafe", 16));
  50 +
  51 + /* stopping at first out-of-base character: */
  52 + printf("%d\n", strtoll("12j", 10));
  53 + printf("%d\n", strtoll("102", 2));
  54 +
  55 + /* base 36: */
  56 + printf("%d\n", strtoll("-0DTrace4EverZ", 36));
  57 +
  58 + /* base 10 is assumed: */
  59 + printf("%d\n", strtoll("1985"));
  60 + printf("%d\n", strtoll("-2012"));
  61 +
  62 + /* empty string: */
  63 + printf("%d\n", strtoll(""));
  64 +
  65 + exit(0);
  66 +}
20 usr/src/cmd/dtrace/test/tst/common/strtoll/tst.strtoll.d.out
... ... @@ -0,0 +1,20 @@
  1 +0
  2 +1
  3 +32
  4 +-32
  5 +8
  6 +42
  7 +9223372036854775807
  8 +-9223372036854775808
  9 +9223372036854775807
  10 +-9223372036854775808
  11 +-9223372036854775808
  12 +9223372036854775807
  13 +3135097598
  14 +12
  15 +2
  16 +-1819882045752187535
  17 +1985
  18 +-2012
  19 +0
  20 +
4 usr/src/common/util/strtolctype.h
@@ -38,6 +38,10 @@ extern "C" {
38 38 * This header file contains a collection of macros that the strtou?ll?
39 39 * functions in common/util use to test characters. What we need is a kernel
40 40 * version of ctype.h.
  41 + *
  42 + * NOTE: These macros are used within several DTrace probe context functions.
  43 + * They must not be altered to make function calls or perform actions not
  44 + * safe in probe context.
41 45 */
42 46
43 47 #if defined(_KERNEL) && !defined(_BOOT)
10 usr/src/lib/libdtrace/common/dt_open.c
@@ -111,8 +111,9 @@
111 111 #define DT_VERS_1_8_1 DT_VERSION_NUMBER(1, 8, 1)
112 112 #define DT_VERS_1_9 DT_VERSION_NUMBER(1, 9, 0)
113 113 #define DT_VERS_1_10 DT_VERSION_NUMBER(1, 10, 0)
114   -#define DT_VERS_LATEST DT_VERS_1_10
115   -#define DT_VERS_STRING "Sun D 1.10"
  114 +#define DT_VERS_1_11 DT_VERSION_NUMBER(1, 11, 0)
  115 +#define DT_VERS_LATEST DT_VERS_1_11
  116 +#define DT_VERS_STRING "Sun D 1.11"
116 117
117 118 const dt_version_t _dtrace_versions[] = {
118 119 DT_VERS_1_0, /* D API 1.0.0 (PSARC 2001/466) Solaris 10 FCS */
@@ -134,6 +135,7 @@ const dt_version_t _dtrace_versions[] = {
134 135 DT_VERS_1_8_1, /* D API 1.8.1 */
135 136 DT_VERS_1_9, /* D API 1.9 */
136 137 DT_VERS_1_10, /* D API 1.10 */
  138 + DT_VERS_1_11, /* D API 1.11 */
137 139 0
138 140 };
139 141
@@ -263,6 +265,8 @@ static const dt_ident_t _dtrace_globals[] = {
263 265 DT_VERS_1_5, &dt_idops_func, "string(int, void *)" },
264 266 { "ipl", DT_IDENT_SCALAR, 0, DIF_VAR_IPL, DT_ATTR_STABCMN, DT_VERS_1_0,
265 267 &dt_idops_type, "uint_t" },
  268 +{ "json", DT_IDENT_FUNC, 0, DIF_SUBR_JSON, DT_ATTR_STABCMN, DT_VERS_1_11,
  269 + &dt_idops_func, "string(const char *, const char *)" },
266 270 { "jstack", DT_IDENT_ACTFUNC, 0, DT_ACT_JSTACK, DT_ATTR_STABCMN, DT_VERS_1_0,
267 271 &dt_idops_func, "stack(...)" },
268 272 { "lltostr", DT_IDENT_FUNC, 0, DIF_SUBR_LLTOSTR, DT_ATTR_STABCMN, DT_VERS_1_0,
@@ -377,6 +381,8 @@ static const dt_ident_t _dtrace_globals[] = {
377 381 &dt_idops_func, "string(const char *, const char *)" },
378 382 { "strtok", DT_IDENT_FUNC, 0, DIF_SUBR_STRTOK, DT_ATTR_STABCMN, DT_VERS_1_1,
379 383 &dt_idops_func, "string(const char *, const char *)" },
  384 +{ "strtoll", DT_IDENT_FUNC, 0, DIF_SUBR_STRTOLL, DT_ATTR_STABCMN, DT_VERS_1_11,
  385 + &dt_idops_func, "int64_t(const char *, [int])" },
380 386 { "substr", DT_IDENT_FUNC, 0, DIF_SUBR_SUBSTR, DT_ATTR_STABCMN, DT_VERS_1_1,
381 387 &dt_idops_func, "string(const char *, int, [int])" },
382 388 { "sum", DT_IDENT_AGGFUNC, 0, DTRACEAGG_SUM, DT_ATTR_STABCMN, DT_VERS_1_0,
593 usr/src/uts/common/dtrace/dtrace.c
@@ -92,6 +92,7 @@
92 92 #include <sys/zone.h>
93 93 #include <sys/socket.h>
94 94 #include <netinet/in.h>
  95 +#include "strtolctype.h"
95 96
96 97 /*
97 98 * DTrace Tunable Variables
@@ -877,6 +878,58 @@ dtrace_vcanload(void *src, dtrace_diftype_t *type, dtrace_mstate_t *mstate,
877 878 }
878 879
879 880 /*
  881 + * Convert a string to a signed integer using safe loads.
  882 + *
  883 + * NOTE: This function uses various macros from strtolctype.h to manipulate
  884 + * digit values, etc -- these have all been checked to ensure they make
  885 + * no additional function calls.
  886 + */
  887 +static int64_t
  888 +dtrace_strtoll(char *input, int base, size_t limit)
  889 +{
  890 + uintptr_t pos = (uintptr_t)input;
  891 + int64_t val = 0;
  892 + int x;
  893 + boolean_t neg = B_FALSE;
  894 + char c, cc, ccc;
  895 + uintptr_t end = pos + limit;
  896 +
  897 + /*
  898 + * Consume any whitespace preceding digits.
  899 + */
  900 + while ((c = dtrace_load8(pos)) == ' ' || c == '\t')
  901 + pos++;
  902 +
  903 + /*
  904 + * Handle an explicit sign if one is present.
  905 + */
  906 + if (c == '-' || c == '+') {
  907 + if (c == '-')
  908 + neg = B_TRUE;
  909 + c = dtrace_load8(++pos);
  910 + }
  911 +
  912 + /*
  913 + * Check for an explicit hexadecimal prefix ("0x" or "0X") and skip it
  914 + * if present.
  915 + */
  916 + if (base == 16 && c == '0' && ((cc = dtrace_load8(pos + 1)) == 'x' ||
  917 + cc == 'X') && isxdigit(ccc = dtrace_load8(pos + 2))) {
  918 + pos += 2;
  919 + c = ccc;
  920 + }
  921 +
  922 + /*
  923 + * Read in contiguous digits until the first non-digit character.
  924 + */
  925 + for (; pos < end && c != '\0' && lisalnum(c) && (x = DIGIT(c)) < base;
  926 + c = dtrace_load8(++pos))
  927 + val = val * base + x;
  928 +
  929 + return (neg ? -val : val);
  930 +}
  931 +
  932 +/*
880 933 * Compare two strings using safe loads.
881 934 */
882 935 static int
@@ -3353,6 +3406,463 @@ dtrace_dif_variable(dtrace_mstate_t *mstate, dtrace_state_t *state, uint64_t v,
3353 3406 }
3354 3407 }
3355 3408
  3409 +
  3410 +typedef enum dtrace_json_state {
  3411 + DTRACE_JSON_REST = 1,
  3412 + DTRACE_JSON_OBJECT,
  3413 + DTRACE_JSON_STRING,
  3414 + DTRACE_JSON_STRING_ESCAPE,
  3415 + DTRACE_JSON_STRING_ESCAPE_UNICODE,
  3416 + DTRACE_JSON_COLON,
  3417 + DTRACE_JSON_COMMA,
  3418 + DTRACE_JSON_VALUE,
  3419 + DTRACE_JSON_IDENTIFIER,
  3420 + DTRACE_JSON_NUMBER,
  3421 + DTRACE_JSON_NUMBER_FRAC,
  3422 + DTRACE_JSON_NUMBER_EXP,
  3423 + DTRACE_JSON_COLLECT_OBJECT
  3424 +} dtrace_json_state_t;
  3425 +
  3426 +/*
  3427 + * This function possesses just enough knowledge about JSON to extract a single
  3428 + * value from a JSON string and store it in the scratch buffer. It is able
  3429 + * to extract nested object values, and members of arrays by index.
  3430 + *
  3431 + * elemlist is a list of JSON keys, stored as packed NUL-terminated strings, to
  3432 + * be looked up as we descend into the object tree. e.g.
  3433 + *
  3434 + * foo[0].bar.baz[32] --> "foo" NUL "0" NUL "bar" NUL "baz" NUL "32" NUL
  3435 + * with nelems = 5.
  3436 + *
  3437 + * The run time of this function must be bounded above by strsize to limit the
  3438 + * amount of work done in probe context. As such, it is implemented as a
  3439 + * simple state machine, reading one character at a time using safe loads
  3440 + * until we find the requested element, hit a parsing error or run off the
  3441 + * end of the object or string.
  3442 + *
  3443 + * As there is no way for a subroutine to return an error without interrupting
  3444 + * clause execution, we simply return NULL in the event of a missing key or any
  3445 + * other error condition. Each NULL return in this function is commented with
  3446 + * the error condition it represents -- parsing or otherwise.
  3447 + *
  3448 + * The set of states for the state machine closely matches the JSON
  3449 + * specification (http://json.org/). Briefly:
  3450 + *
  3451 + * DTRACE_JSON_REST:
  3452 + * Skip whitespace until we find either a top-level Object, moving
  3453 + * to DTRACE_JSON_OBJECT; or an Array, moving to DTRACE_JSON_VALUE.
  3454 + *
  3455 + * DTRACE_JSON_OBJECT:
  3456 + * Locate the next key String in an Object. Sets a flag to denote
  3457 + * the next String as a key string and moves to DTRACE_JSON_STRING.
  3458 + *
  3459 + * DTRACE_JSON_COLON:
  3460 + * Skip whitespace until we find the colon that separates key Strings
  3461 + * from their values. Once found, move to DTRACE_JSON_VALUE.
  3462 + *
  3463 + * DTRACE_JSON_VALUE:
  3464 + * Detects the type of the next value (String, Number, Identifier, Object
  3465 + * or Array) and routes to the states that process that type. Here we also
  3466 + * deal with the element selector list if we are requested to traverse down
  3467 + * into the object tree.
  3468 + *
  3469 + * DTRACE_JSON_COMMA:
  3470 + * Skip whitespace until we find the comma that separates key-value pairs
  3471 + * in Objects (returning to DTRACE_JSON_OBJECT) or values in Arrays
  3472 + * (similarly DTRACE_JSON_VALUE). All following literal value processing
  3473 + * states return to this state at the end of their value, unless otherwise
  3474 + * noted.
  3475 + *
  3476 + * DTRACE_JSON_NUMBER, DTRACE_JSON_NUMBER_FRAC, DTRACE_JSON_NUMBER_EXP:
  3477 + * Processes a Number literal from the JSON, including any exponent
  3478 + * component that may be present. Numbers are returned as strings, which
  3479 + * may be passed to strtoll() if an integer is required.
  3480 + *
  3481 + * DTRACE_JSON_IDENTIFIER:
  3482 + * Processes a "true", "false" or "null" literal in the JSON.
  3483 + *
  3484 + * DTRACE_JSON_STRING, DTRACE_JSON_STRING_ESCAPE,
  3485 + * DTRACE_JSON_STRING_ESCAPE_UNICODE: