diff options
Diffstat (limited to 'cddl/contrib')
83 files changed, 5578 insertions, 164 deletions
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/dtrace.c b/cddl/contrib/opensolaris/cmd/dtrace/dtrace.c index a745ceb..4cbb866 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/dtrace.c +++ b/cddl/contrib/opensolaris/cmd/dtrace/dtrace.c @@ -25,6 +25,7 @@ */ /* * Copyright (c) 2012 by Delphix. All rights reserved. + * Copyright (c) 2013, Joyent, Inc. All rights reserved. */ #include <sys/types.h> @@ -513,6 +514,7 @@ static void print_probe_info(const dtrace_probeinfo_t *p) { char buf[BUFSIZ]; + char *user; int i; oprintf("\n\tProbe Description Attributes\n"); @@ -536,10 +538,14 @@ print_probe_info(const dtrace_probeinfo_t *p) oprintf("\n\tArgument Types\n"); for (i = 0; i < p->dtp_argc; i++) { + if (p->dtp_argv[i].dtt_flags & DTT_FL_USER) + user = "userland "; + else + user = ""; if (ctf_type_name(p->dtp_argv[i].dtt_ctfp, p->dtp_argv[i].dtt_type, buf, sizeof (buf)) == NULL) (void) strlcpy(buf, "(unknown)", sizeof (buf)); - oprintf("\t\targs[%d]: %s\n", i, buf); + oprintf("\t\targs[%d]: %s%s\n", i, user, buf); } if (p->dtp_argc == 0) diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.aggencoding.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.aggencoding.d new file mode 100644 index 0000000..a594afc --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.aggencoding.d @@ -0,0 +1,32 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright (c) 2013 Joyent, Inc. All rights reserved. + */ + +#pragma D option quiet +#pragma D option encoding=utf8 +#pragma D option aggzoom + +tick-1ms +/i++ < 320/ +{ + @ = lquantize(i, 0, 640, 1, i); + @ = lquantize(641 - i, 0, 640, 1, i); +} + +tick-1ms +/i == 320/ +{ + printa(@); + exit(0); +} diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.aggencoding.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.aggencoding.d.out new file mode 100644 index 0000000..68482ff --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.aggencoding.d.out @@ -0,0 +1,646 @@ + + + value ------------- Distribution ------------- count + 0 | 0 + 1 | 1 + 2 |▏ 2 + 3 |▎ 3 + 4 |▍ 4 + 5 |▌ 5 + 6 |▋ 6 + 7 |▊ 7 + 8 |▉ 8 + 9 |█ 9 + 10 |█▏ 10 + 11 |█▎ 11 + 12 |█▍ 12 + 13 |█▌ 13 + 14 |█▋ 14 + 15 |█▊ 15 + 16 |█▉ 16 + 17 |██ 17 + 18 |██▏ 18 + 19 |██▎ 19 + 20 |██▍ 20 + 21 |██▍ 21 + 22 |██▌ 22 + 23 |██▋ 23 + 24 |██▊ 24 + 25 |██▉ 25 + 26 |███ 26 + 27 |███▏ 27 + 28 |███▎ 28 + 29 |███▍ 29 + 30 |███▌ 30 + 31 |███▋ 31 + 32 |███▊ 32 + 33 |███▉ 33 + 34 |████ 34 + 35 |████▏ 35 + 36 |████▎ 36 + 37 |████▍ 37 + 38 |████▌ 38 + 39 |████▋ 39 + 40 |████▊ 40 + 41 |████▊ 41 + 42 |████▉ 42 + 43 |█████ 43 + 44 |█████▏ 44 + 45 |█████▎ 45 + 46 |█████▍ 46 + 47 |█████▌ 47 + 48 |█████▋ 48 + 49 |█████▊ 49 + 50 |█████▉ 50 + 51 |██████ 51 + 52 |██████▏ 52 + 53 |██████▎ 53 + 54 |██████▍ 54 + 55 |██████▌ 55 + 56 |██████▋ 56 + 57 |██████▊ 57 + 58 |██████▉ 58 + 59 |███████ 59 + 60 |███████▏ 60 + 61 |███████▏ 61 + 62 |███████▎ 62 + 63 |███████▍ 63 + 64 |███████▌ 64 + 65 |███████▋ 65 + 66 |███████▊ 66 + 67 |███████▉ 67 + 68 |████████ 68 + 69 |████████▏ 69 + 70 |████████▎ 70 + 71 |████████▍ 71 + 72 |████████▌ 72 + 73 |████████▋ 73 + 74 |████████▊ 74 + 75 |████████▉ 75 + 76 |█████████ 76 + 77 |█████████▏ 77 + 78 |█████████▎ 78 + 79 |█████████▍ 79 + 80 |█████████▌ 80 + 81 |█████████▌ 81 + 82 |█████████▋ 82 + 83 |█████████▊ 83 + 84 |█████████▉ 84 + 85 |██████████ 85 + 86 |██████████▏ 86 + 87 |██████████▎ 87 + 88 |██████████▍ 88 + 89 |██████████▌ 89 + 90 |██████████▋ 90 + 91 |██████████▊ 91 + 92 |██████████▉ 92 + 93 |███████████ 93 + 94 |███████████▏ 94 + 95 |███████████▎ 95 + 96 |███████████▍ 96 + 97 |███████████▌ 97 + 98 |███████████▋ 98 + 99 |███████████▊ 99 + 100 |███████████▉ 100 + 101 |███████████▉ 101 + 102 |████████████ 102 + 103 |████████████▏ 103 + 104 |████████████▎ 104 + 105 |████████████▍ 105 + 106 |████████████▌ 106 + 107 |████████████▋ 107 + 108 |████████████▊ 108 + 109 |████████████▉ 109 + 110 |█████████████ 110 + 111 |█████████████▏ 111 + 112 |█████████████▎ 112 + 113 |█████████████▍ 113 + 114 |█████████████▌ 114 + 115 |█████████████▋ 115 + 116 |█████████████▊ 116 + 117 |█████████████▉ 117 + 118 |██████████████ 118 + 119 |██████████████▏ 119 + 120 |██████████████▎ 120 + 121 |██████████████▎ 121 + 122 |██████████████▍ 122 + 123 |██████████████▌ 123 + 124 |██████████████▋ 124 + 125 |██████████████▊ 125 + 126 |██████████████▉ 126 + 127 |███████████████ 127 + 128 |███████████████▏ 128 + 129 |███████████████▎ 129 + 130 |███████████████▍ 130 + 131 |███████████████▌ 131 + 132 |███████████████▋ 132 + 133 |███████████████▊ 133 + 134 |███████████████▉ 134 + 135 |████████████████ 135 + 136 |████████████████▏ 136 + 137 |████████████████▎ 137 + 138 |████████████████▍ 138 + 139 |████████████████▌ 139 + 140 |████████████████▋ 140 + 141 |████████████████▋ 141 + 142 |████████████████▊ 142 + 143 |████████████████▉ 143 + 144 |█████████████████ 144 + 145 |█████████████████▏ 145 + 146 |█████████████████▎ 146 + 147 |█████████████████▍ 147 + 148 |█████████████████▌ 148 + 149 |█████████████████▋ 149 + 150 |█████████████████▊ 150 + 151 |█████████████████▉ 151 + 152 |██████████████████ 152 + 153 |██████████████████▏ 153 + 154 |██████████████████▎ 154 + 155 |██████████████████▍ 155 + 156 |██████████████████▌ 156 + 157 |██████████████████▋ 157 + 158 |██████████████████▊ 158 + 159 |██████████████████▉ 159 + 160 |███████████████████ 160 + 161 |███████████████████ 161 + 162 |███████████████████▏ 162 + 163 |███████████████████▎ 163 + 164 |███████████████████▍ 164 + 165 |███████████████████▌ 165 + 166 |███████████████████▋ 166 + 167 |███████████████████▊ 167 + 168 |███████████████████▉ 168 + 169 |████████████████████ 169 + 170 |████████████████████▏ 170 + 171 |████████████████████▎ 171 + 172 |████████████████████▍ 172 + 173 |████████████████████▌ 173 + 174 |████████████████████▋ 174 + 175 |████████████████████▊ 175 + 176 |████████████████████▉ 176 + 177 |█████████████████████ 177 + 178 |█████████████████████▏ 178 + 179 |█████████████████████▎ 179 + 180 |█████████████████████▍ 180 + 181 |█████████████████████▍ 181 + 182 |█████████████████████▌ 182 + 183 |█████████████████████▋ 183 + 184 |█████████████████████▊ 184 + 185 |█████████████████████▉ 185 + 186 |██████████████████████ 186 + 187 |██████████████████████▏ 187 + 188 |██████████████████████▎ 188 + 189 |██████████████████████▍ 189 + 190 |██████████████████████▌ 190 + 191 |██████████████████████▋ 191 + 192 |██████████████████████▊ 192 + 193 |██████████████████████▉ 193 + 194 |███████████████████████ 194 + 195 |███████████████████████▏ 195 + 196 |███████████████████████▎ 196 + 197 |███████████████████████▍ 197 + 198 |███████████████████████▌ 198 + 199 |███████████████████████▋ 199 + 200 |███████████████████████▊ 200 + 201 |███████████████████████▊ 201 + 202 |███████████████████████▉ 202 + 203 |████████████████████████ 203 + 204 |████████████████████████▏ 204 + 205 |████████████████████████▎ 205 + 206 |████████████████████████▍ 206 + 207 |████████████████████████▌ 207 + 208 |████████████████████████▋ 208 + 209 |████████████████████████▊ 209 + 210 |████████████████████████▉ 210 + 211 |█████████████████████████ 211 + 212 |█████████████████████████▏ 212 + 213 |█████████████████████████▎ 213 + 214 |█████████████████████████▍ 214 + 215 |█████████████████████████▌ 215 + 216 |█████████████████████████▋ 216 + 217 |█████████████████████████▊ 217 + 218 |█████████████████████████▉ 218 + 219 |██████████████████████████ 219 + 220 |██████████████████████████▏ 220 + 221 |██████████████████████████▏ 221 + 222 |██████████████████████████▎ 222 + 223 |██████████████████████████▍ 223 + 224 |██████████████████████████▌ 224 + 225 |██████████████████████████▋ 225 + 226 |██████████████████████████▊ 226 + 227 |██████████████████████████▉ 227 + 228 |███████████████████████████ 228 + 229 |███████████████████████████▏ 229 + 230 |███████████████████████████▎ 230 + 231 |███████████████████████████▍ 231 + 232 |███████████████████████████▌ 232 + 233 |███████████████████████████▋ 233 + 234 |███████████████████████████▊ 234 + 235 |███████████████████████████▉ 235 + 236 |████████████████████████████ 236 + 237 |████████████████████████████▏ 237 + 238 |████████████████████████████▎ 238 + 239 |████████████████████████████▍ 239 + 240 |████████████████████████████▌ 240 + 241 |████████████████████████████▌ 241 + 242 |████████████████████████████▋ 242 + 243 |████████████████████████████▊ 243 + 244 |████████████████████████████▉ 244 + 245 |█████████████████████████████ 245 + 246 |█████████████████████████████▏ 246 + 247 |█████████████████████████████▎ 247 + 248 |█████████████████████████████▍ 248 + 249 |█████████████████████████████▌ 249 + 250 |█████████████████████████████▋ 250 + 251 |█████████████████████████████▊ 251 + 252 |█████████████████████████████▉ 252 + 253 |██████████████████████████████ 253 + 254 |██████████████████████████████▏ 254 + 255 |██████████████████████████████▎ 255 + 256 |██████████████████████████████▍ 256 + 257 |██████████████████████████████▌ 257 + 258 |██████████████████████████████▋ 258 + 259 |██████████████████████████████▊ 259 + 260 |██████████████████████████████▉ 260 + 261 |██████████████████████████████▉ 261 + 262 |███████████████████████████████ 262 + 263 |███████████████████████████████▏ 263 + 264 |███████████████████████████████▎ 264 + 265 |███████████████████████████████▍ 265 + 266 |███████████████████████████████▌ 266 + 267 |███████████████████████████████▋ 267 + 268 |███████████████████████████████▊ 268 + 269 |███████████████████████████████▉ 269 + 270 |████████████████████████████████ 270 + 271 |████████████████████████████████▏ 271 + 272 |████████████████████████████████▎ 272 + 273 |████████████████████████████████▍ 273 + 274 |████████████████████████████████▌ 274 + 275 |████████████████████████████████▋ 275 + 276 |████████████████████████████████▊ 276 + 277 |████████████████████████████████▉ 277 + 278 |█████████████████████████████████ 278 + 279 |█████████████████████████████████▏ 279 + 280 |█████████████████████████████████▎ 280 + 281 |█████████████████████████████████▎ 281 + 282 |█████████████████████████████████▍ 282 + 283 |█████████████████████████████████▌ 283 + 284 |█████████████████████████████████▋ 284 + 285 |█████████████████████████████████▊ 285 + 286 |█████████████████████████████████▉ 286 + 287 |██████████████████████████████████ 287 + 288 |██████████████████████████████████▏ 288 + 289 |██████████████████████████████████▎ 289 + 290 |██████████████████████████████████▍ 290 + 291 |██████████████████████████████████▌ 291 + 292 |██████████████████████████████████▋ 292 + 293 |██████████████████████████████████▊ 293 + 294 |██████████████████████████████████▉ 294 + 295 |███████████████████████████████████ 295 + 296 |███████████████████████████████████▏ 296 + 297 |███████████████████████████████████▎ 297 + 298 |███████████████████████████████████▍ 298 + 299 |███████████████████████████████████▌ 299 + 300 |███████████████████████████████████▋ 300 + 301 |███████████████████████████████████▋ 301 + 302 |███████████████████████████████████▊ 302 + 303 |███████████████████████████████████▉ 303 + 304 |████████████████████████████████████ 304 + 305 |████████████████████████████████████▏ 305 + 306 |████████████████████████████████████▎ 306 + 307 |████████████████████████████████████▍ 307 + 308 |████████████████████████████████████▌ 308 + 309 |████████████████████████████████████▋ 309 + 310 |████████████████████████████████████▊ 310 + 311 |████████████████████████████████████▉ 311 + 312 |█████████████████████████████████████ 312 + 313 |█████████████████████████████████████▏ 313 + 314 |█████████████████████████████████████▎ 314 + 315 |█████████████████████████████████████▍ 315 + 316 |█████████████████████████████████████▌ 316 + 317 |█████████████████████████████████████▋ 317 + 318 |█████████████████████████████████████▊ 318 + 319 |█████████████████████████████████████▉ 319 + 320 |██████████████████████████████████████ 320 + 321 |██████████████████████████████████████ 320 + 322 |█████████████████████████████████████▉ 319 + 323 |█████████████████████████████████████▊ 318 + 324 |█████████████████████████████████████▋ 317 + 325 |█████████████████████████████████████▌ 316 + 326 |█████████████████████████████████████▍ 315 + 327 |█████████████████████████████████████▎ 314 + 328 |█████████████████████████████████████▏ 313 + 329 |█████████████████████████████████████ 312 + 330 |████████████████████████████████████▉ 311 + 331 |████████████████████████████████████▊ 310 + 332 |████████████████████████████████████▋ 309 + 333 |████████████████████████████████████▌ 308 + 334 |████████████████████████████████████▍ 307 + 335 |████████████████████████████████████▎ 306 + 336 |████████████████████████████████████▏ 305 + 337 |████████████████████████████████████ 304 + 338 |███████████████████████████████████▉ 303 + 339 |███████████████████████████████████▊ 302 + 340 |███████████████████████████████████▋ 301 + 341 |███████████████████████████████████▋ 300 + 342 |███████████████████████████████████▌ 299 + 343 |███████████████████████████████████▍ 298 + 344 |███████████████████████████████████▎ 297 + 345 |███████████████████████████████████▏ 296 + 346 |███████████████████████████████████ 295 + 347 |██████████████████████████████████▉ 294 + 348 |██████████████████████████████████▊ 293 + 349 |██████████████████████████████████▋ 292 + 350 |██████████████████████████████████▌ 291 + 351 |██████████████████████████████████▍ 290 + 352 |██████████████████████████████████▎ 289 + 353 |██████████████████████████████████▏ 288 + 354 |██████████████████████████████████ 287 + 355 |█████████████████████████████████▉ 286 + 356 |█████████████████████████████████▊ 285 + 357 |█████████████████████████████████▋ 284 + 358 |█████████████████████████████████▌ 283 + 359 |█████████████████████████████████▍ 282 + 360 |█████████████████████████████████▎ 281 + 361 |█████████████████████████████████▎ 280 + 362 |█████████████████████████████████▏ 279 + 363 |█████████████████████████████████ 278 + 364 |████████████████████████████████▉ 277 + 365 |████████████████████████████████▊ 276 + 366 |████████████████████████████████▋ 275 + 367 |████████████████████████████████▌ 274 + 368 |████████████████████████████████▍ 273 + 369 |████████████████████████████████▎ 272 + 370 |████████████████████████████████▏ 271 + 371 |████████████████████████████████ 270 + 372 |███████████████████████████████▉ 269 + 373 |███████████████████████████████▊ 268 + 374 |███████████████████████████████▋ 267 + 375 |███████████████████████████████▌ 266 + 376 |███████████████████████████████▍ 265 + 377 |███████████████████████████████▎ 264 + 378 |███████████████████████████████▏ 263 + 379 |███████████████████████████████ 262 + 380 |██████████████████████████████▉ 261 + 381 |██████████████████████████████▉ 260 + 382 |██████████████████████████████▊ 259 + 383 |██████████████████████████████▋ 258 + 384 |██████████████████████████████▌ 257 + 385 |██████████████████████████████▍ 256 + 386 |██████████████████████████████▎ 255 + 387 |██████████████████████████████▏ 254 + 388 |██████████████████████████████ 253 + 389 |█████████████████████████████▉ 252 + 390 |█████████████████████████████▊ 251 + 391 |█████████████████████████████▋ 250 + 392 |█████████████████████████████▌ 249 + 393 |█████████████████████████████▍ 248 + 394 |█████████████████████████████▎ 247 + 395 |█████████████████████████████▏ 246 + 396 |█████████████████████████████ 245 + 397 |████████████████████████████▉ 244 + 398 |████████████████████████████▊ 243 + 399 |████████████████████████████▋ 242 + 400 |████████████████████████████▌ 241 + 401 |████████████████████████████▌ 240 + 402 |████████████████████████████▍ 239 + 403 |████████████████████████████▎ 238 + 404 |████████████████████████████▏ 237 + 405 |████████████████████████████ 236 + 406 |███████████████████████████▉ 235 + 407 |███████████████████████████▊ 234 + 408 |███████████████████████████▋ 233 + 409 |███████████████████████████▌ 232 + 410 |███████████████████████████▍ 231 + 411 |███████████████████████████▎ 230 + 412 |███████████████████████████▏ 229 + 413 |███████████████████████████ 228 + 414 |██████████████████████████▉ 227 + 415 |██████████████████████████▊ 226 + 416 |██████████████████████████▋ 225 + 417 |██████████████████████████▌ 224 + 418 |██████████████████████████▍ 223 + 419 |██████████████████████████▎ 222 + 420 |██████████████████████████▏ 221 + 421 |██████████████████████████▏ 220 + 422 |██████████████████████████ 219 + 423 |█████████████████████████▉ 218 + 424 |█████████████████████████▊ 217 + 425 |█████████████████████████▋ 216 + 426 |█████████████████████████▌ 215 + 427 |█████████████████████████▍ 214 + 428 |█████████████████████████▎ 213 + 429 |█████████████████████████▏ 212 + 430 |█████████████████████████ 211 + 431 |████████████████████████▉ 210 + 432 |████████████████████████▊ 209 + 433 |████████████████████████▋ 208 + 434 |████████████████████████▌ 207 + 435 |████████████████████████▍ 206 + 436 |████████████████████████▎ 205 + 437 |████████████████████████▏ 204 + 438 |████████████████████████ 203 + 439 |███████████████████████▉ 202 + 440 |███████████████████████▊ 201 + 441 |███████████████████████▊ 200 + 442 |███████████████████████▋ 199 + 443 |███████████████████████▌ 198 + 444 |███████████████████████▍ 197 + 445 |███████████████████████▎ 196 + 446 |███████████████████████▏ 195 + 447 |███████████████████████ 194 + 448 |██████████████████████▉ 193 + 449 |██████████████████████▊ 192 + 450 |██████████████████████▋ 191 + 451 |██████████████████████▌ 190 + 452 |██████████████████████▍ 189 + 453 |██████████████████████▎ 188 + 454 |██████████████████████▏ 187 + 455 |██████████████████████ 186 + 456 |█████████████████████▉ 185 + 457 |█████████████████████▊ 184 + 458 |█████████████████████▋ 183 + 459 |█████████████████████▌ 182 + 460 |█████████████████████▍ 181 + 461 |█████████████████████▍ 180 + 462 |█████████████████████▎ 179 + 463 |█████████████████████▏ 178 + 464 |█████████████████████ 177 + 465 |████████████████████▉ 176 + 466 |████████████████████▊ 175 + 467 |████████████████████▋ 174 + 468 |████████████████████▌ 173 + 469 |████████████████████▍ 172 + 470 |████████████████████▎ 171 + 471 |████████████████████▏ 170 + 472 |████████████████████ 169 + 473 |███████████████████▉ 168 + 474 |███████████████████▊ 167 + 475 |███████████████████▋ 166 + 476 |███████████████████▌ 165 + 477 |███████████████████▍ 164 + 478 |███████████████████▎ 163 + 479 |███████████████████▏ 162 + 480 |███████████████████ 161 + 481 |███████████████████ 160 + 482 |██████████████████▉ 159 + 483 |██████████████████▊ 158 + 484 |██████████████████▋ 157 + 485 |██████████████████▌ 156 + 486 |██████████████████▍ 155 + 487 |██████████████████▎ 154 + 488 |██████████████████▏ 153 + 489 |██████████████████ 152 + 490 |█████████████████▉ 151 + 491 |█████████████████▊ 150 + 492 |█████████████████▋ 149 + 493 |█████████████████▌ 148 + 494 |█████████████████▍ 147 + 495 |█████████████████▎ 146 + 496 |█████████████████▏ 145 + 497 |█████████████████ 144 + 498 |████████████████▉ 143 + 499 |████████████████▊ 142 + 500 |████████████████▋ 141 + 501 |████████████████▋ 140 + 502 |████████████████▌ 139 + 503 |████████████████▍ 138 + 504 |████████████████▎ 137 + 505 |████████████████▏ 136 + 506 |████████████████ 135 + 507 |███████████████▉ 134 + 508 |███████████████▊ 133 + 509 |███████████████▋ 132 + 510 |███████████████▌ 131 + 511 |███████████████▍ 130 + 512 |███████████████▎ 129 + 513 |███████████████▏ 128 + 514 |███████████████ 127 + 515 |██████████████▉ 126 + 516 |██████████████▊ 125 + 517 |██████████████▋ 124 + 518 |██████████████▌ 123 + 519 |██████████████▍ 122 + 520 |██████████████▎ 121 + 521 |██████████████▎ 120 + 522 |██████████████▏ 119 + 523 |██████████████ 118 + 524 |█████████████▉ 117 + 525 |█████████████▊ 116 + 526 |█████████████▋ 115 + 527 |█████████████▌ 114 + 528 |█████████████▍ 113 + 529 |█████████████▎ 112 + 530 |█████████████▏ 111 + 531 |█████████████ 110 + 532 |████████████▉ 109 + 533 |████████████▊ 108 + 534 |████████████▋ 107 + 535 |████████████▌ 106 + 536 |████████████▍ 105 + 537 |████████████▎ 104 + 538 |████████████▏ 103 + 539 |████████████ 102 + 540 |███████████▉ 101 + 541 |███████████▉ 100 + 542 |███████████▊ 99 + 543 |███████████▋ 98 + 544 |███████████▌ 97 + 545 |███████████▍ 96 + 546 |███████████▎ 95 + 547 |███████████▏ 94 + 548 |███████████ 93 + 549 |██████████▉ 92 + 550 |██████████▊ 91 + 551 |██████████▋ 90 + 552 |██████████▌ 89 + 553 |██████████▍ 88 + 554 |██████████▎ 87 + 555 |██████████▏ 86 + 556 |██████████ 85 + 557 |█████████▉ 84 + 558 |█████████▊ 83 + 559 |█████████▋ 82 + 560 |█████████▌ 81 + 561 |█████████▌ 80 + 562 |█████████▍ 79 + 563 |█████████▎ 78 + 564 |█████████▏ 77 + 565 |█████████ 76 + 566 |████████▉ 75 + 567 |████████▊ 74 + 568 |████████▋ 73 + 569 |████████▌ 72 + 570 |████████▍ 71 + 571 |████████▎ 70 + 572 |████████▏ 69 + 573 |████████ 68 + 574 |███████▉ 67 + 575 |███████▊ 66 + 576 |███████▋ 65 + 577 |███████▌ 64 + 578 |███████▍ 63 + 579 |███████▎ 62 + 580 |███████▏ 61 + 581 |███████▏ 60 + 582 |███████ 59 + 583 |██████▉ 58 + 584 |██████▊ 57 + 585 |██████▋ 56 + 586 |██████▌ 55 + 587 |██████▍ 54 + 588 |██████▎ 53 + 589 |██████▏ 52 + 590 |██████ 51 + 591 |█████▉ 50 + 592 |█████▊ 49 + 593 |█████▋ 48 + 594 |█████▌ 47 + 595 |█████▍ 46 + 596 |█████▎ 45 + 597 |█████▏ 44 + 598 |█████ 43 + 599 |████▉ 42 + 600 |████▊ 41 + 601 |████▊ 40 + 602 |████▋ 39 + 603 |████▌ 38 + 604 |████▍ 37 + 605 |████▎ 36 + 606 |████▏ 35 + 607 |████ 34 + 608 |███▉ 33 + 609 |███▊ 32 + 610 |███▋ 31 + 611 |███▌ 30 + 612 |███▍ 29 + 613 |███▎ 28 + 614 |███▏ 27 + 615 |███ 26 + 616 |██▉ 25 + 617 |██▊ 24 + 618 |██▋ 23 + 619 |██▌ 22 + 620 |██▍ 21 + 621 |██▍ 20 + 622 |██▎ 19 + 623 |██▏ 18 + 624 |██ 17 + 625 |█▉ 16 + 626 |█▊ 15 + 627 |█▋ 14 + 628 |█▌ 13 + 629 |█▍ 12 + 630 |█▎ 11 + 631 |█▏ 10 + 632 |█ 9 + 633 |▉ 8 + 634 |▊ 7 + 635 |▋ 6 + 636 |▌ 5 + 637 |▍ 4 + 638 |▎ 3 + 639 |▏ 2 + >= 640 | 1 + + diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.agghist.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.agghist.d new file mode 100644 index 0000000..317aece --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.agghist.d @@ -0,0 +1,46 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright (c) 2013 Joyent, Inc. All rights reserved. + */ + +#pragma D option agghist +#pragma D option quiet + +BEGIN +{ + @["demerit"] = sum(-10); + @["wtf"] = sum(10); + @["bot"] = sum(20); + + @bagnoogle["SOAP/XML"] = sum(1); + @bagnoogle["XACML store"] = sum(5); + @bagnoogle["SAML token"] = sum(6); + + @stalloogle["breakfast"] = sum(-5); + @stalloogle["non-diet pepsi"] = sum(-20); + @stalloogle["parrot"] = sum(-100); + + printa(@); + printa(@bagnoogle); + printa(@stalloogle); + + printf("\nzoomed:"); + + setopt("aggzoom"); + printa(@); + printa(@bagnoogle); + printa(@stalloogle); + + exit(0); +} + diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.agghist.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.agghist.d.out new file mode 100644 index 0000000..d76e4da --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.agghist.d.out @@ -0,0 +1,38 @@ + + + key ------------- Distribution ------------- count + demerit @@@@@| -10 + wtf |@@@@@ 10 + bot |@@@@@@@@@@ 20 + + + key ------------- Distribution ------------- count + SOAP/XML |@@@ 1 + XACML store |@@@@@@@@@@@@@@@@@ 5 + SAML token |@@@@@@@@@@@@@@@@@@@@ 6 + + + key ------------- Distribution ------------- count + parrot @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -100 + non-diet pepsi @@@@@@| -20 + breakfast @@| -5 + +zoomed: + + key ------------- Distribution ------------- count + demerit @@@@@@@@@@| -10 + wtf |@@@@@@@@@@ 10 + bot |@@@@@@@@@@@@@@@@@@@ 20 + + + key ------------- Distribution ------------- count + SOAP/XML |@@@@@@@ 1 + XACML store |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 5 + SAML token |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 6 + + + key ------------- Distribution ------------- count + parrot @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -100 + non-diet pepsi @@@@@@@@| -20 + breakfast @@| -5 + diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.aggpack.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.aggpack.d new file mode 100644 index 0000000..c9fdba7 --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.aggpack.d @@ -0,0 +1,53 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright (c) 2013 Joyent, Inc. All rights reserved. + */ + +#pragma D option aggpack +#pragma D option encoding=ascii +#pragma D option quiet + +BEGIN +{ + @x = quantize(1 << 32); + @y[1] = quantize(1); + @z["mumble"] = quantize(1); + @xx["foo", (char)1, (short)2, (long)3] = quantize(1); + + @neg = lquantize(-10, -10, 20, 1, -1); + @neg = lquantize(-5, -10, 20, 1, 1); + @neg = lquantize(0, -10, 20, 1, 1); + + i = 0; +} + +tick-1ms +{ + @a[i] = quantize(0, i); + @a[i] = quantize(1, 100 - i); + i++; +} + +tick-1ms +/i > 100/ +{ + exit(0); +} + +END +{ + setopt("aggzoom", "true"); + printa(@neg); + setopt("aggzoom", "false"); + printa(@neg); +} diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.aggpack.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.aggpack.d.out new file mode 100644 index 0000000..5300ebd --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.aggpack.d.out @@ -0,0 +1,124 @@ + + + min .--------------------------------. max | count + < -10 : V X X : >= 20 | 1 + + + min .--------------------------------. max | count + < -10 : v x x : >= 20 | 1 + + + min .---. max | count + 2147483648 : X : 8589934592 | 1 + + key min .---. max | count + 1 0 : X : 2 | 1 + + key min .---. max | count + mumble 0 : X : 2 | 1 + + key min .---. max | count + foo 1 2 3 0 : X : 2 | 1 + + key min .---. max | count + 100 0 :X : 2 | 100 + 99 0 :X_ : 2 | 100 + 98 0 :X_ : 2 | 100 + 97 0 :X_ : 2 | 100 + 96 0 :X_ : 2 | 100 + 95 0 :X_ : 2 | 100 + 94 0 :X_ : 2 | 100 + 93 0 :X_ : 2 | 100 + 92 0 :X_ : 2 | 100 + 91 0 :X_ : 2 | 100 + 90 0 :X_ : 2 | 100 + 89 0 :X_ : 2 | 100 + 88 0 :X_ : 2 | 100 + 87 0 :X_ : 2 | 100 + 86 0 :X_ : 2 | 100 + 85 0 :X_ : 2 | 100 + 84 0 :X_ : 2 | 100 + 83 0 :X_ : 2 | 100 + 82 0 :X_ : 2 | 100 + 81 0 :X_ : 2 | 100 + 80 0 :X_ : 2 | 100 + 79 0 :X_ : 2 | 100 + 78 0 :xx : 2 | 100 + 77 0 :xx : 2 | 100 + 76 0 :xx : 2 | 100 + 75 0 :xx : 2 | 100 + 74 0 :xx : 2 | 100 + 73 0 :xx : 2 | 100 + 72 0 :xx : 2 | 100 + 71 0 :xx : 2 | 100 + 70 0 :xx : 2 | 100 + 69 0 :xx : 2 | 100 + 68 0 :xx : 2 | 100 + 67 0 :xx : 2 | 100 + 66 0 :xx : 2 | 100 + 65 0 :xx : 2 | 100 + 64 0 :xx : 2 | 100 + 63 0 :xx : 2 | 100 + 62 0 :xx : 2 | 100 + 61 0 :xx : 2 | 100 + 60 0 :xx : 2 | 100 + 59 0 :xx : 2 | 100 + 58 0 :xx : 2 | 100 + 57 0 :xx : 2 | 100 + 56 0 :xx : 2 | 100 + 55 0 :xx : 2 | 100 + 54 0 :xx : 2 | 100 + 53 0 :xx : 2 | 100 + 52 0 :xx : 2 | 100 + 51 0 :xx : 2 | 100 + 50 0 :xx : 2 | 100 + 49 0 :xx : 2 | 100 + 48 0 :xx : 2 | 100 + 47 0 :xx : 2 | 100 + 46 0 :xx : 2 | 100 + 45 0 :xx : 2 | 100 + 44 0 :xx : 2 | 100 + 43 0 :xx : 2 | 100 + 42 0 :xx : 2 | 100 + 41 0 :xx : 2 | 100 + 40 0 :xx : 2 | 100 + 39 0 :xx : 2 | 100 + 38 0 :xx : 2 | 100 + 37 0 :xx : 2 | 100 + 36 0 :xx : 2 | 100 + 35 0 :xx : 2 | 100 + 34 0 :xx : 2 | 100 + 33 0 :xx : 2 | 100 + 32 0 :xx : 2 | 100 + 31 0 :xx : 2 | 100 + 30 0 :xx : 2 | 100 + 29 0 :xx : 2 | 100 + 28 0 :xx : 2 | 100 + 27 0 :xx : 2 | 100 + 26 0 :xx : 2 | 100 + 25 0 :xx : 2 | 100 + 24 0 :xx : 2 | 100 + 23 0 :xx : 2 | 100 + 22 0 :xx : 2 | 100 + 21 0 :_X : 2 | 100 + 20 0 :_X : 2 | 100 + 19 0 :_X : 2 | 100 + 18 0 :_X : 2 | 100 + 17 0 :_X : 2 | 100 + 16 0 :_X : 2 | 100 + 15 0 :_X : 2 | 100 + 14 0 :_X : 2 | 100 + 13 0 :_X : 2 | 100 + 12 0 :_X : 2 | 100 + 11 0 :_X : 2 | 100 + 10 0 :_X : 2 | 100 + 9 0 :_X : 2 | 100 + 8 0 :_X : 2 | 100 + 7 0 :_X : 2 | 100 + 6 0 :_X : 2 | 100 + 5 0 :_X : 2 | 100 + 4 0 :_X : 2 | 100 + 3 0 :_X : 2 | 100 + 2 0 :_X : 2 | 100 + 1 0 :_X : 2 | 100 + 0 0 : X : 2 | 100 diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.aggpackbanner.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.aggpackbanner.ksh new file mode 100644 index 0000000..f055a08 --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.aggpackbanner.ksh @@ -0,0 +1,75 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright (c) 2013 Joyent, Inc. All rights reserved. +# + +let width=8 + +function outputchar +{ + banner $3 | /bin/nawk -v line=$1 -v pos=$2 -v width=$width '{ \ + for (i = 1; i <= length($0); i++) { \ + if (substr($0, i, 1) == " ") \ + continue; \ + printf("\t@letter%d[%d] = lquantize(%d, 0, 40, 1);\n", \ + line, NR, i + (pos * width)); + } \ + }' +} + +function outputstr +{ + let pos=0; + let line=0 + + printf "#pragma D option aggpack\n#pragma D option aggsortkey\n" + + printf "BEGIN\n{\n" + for c in `echo "$1" | /bin/nawk '{ \ + for (i = 1; i <= length($0); i++) { \ + c = substr($0, i, 1); \ + printf("%s\n", c == " " ? "space" : \ + c == "\n" ? "newline" : c); \ + } \ + }'`; do + if [[ "$c" == "space" ]]; then + let line=line+1 + let pos=0 + continue + fi + + outputchar $line $pos $c + let pos=pos+1 + done + + let i=0 + + while [[ $i -le $line ]]; do + printf "\tprinta(@letter%d);\n" $i + let i=i+1 + done + printf "\texit(0);\n}\n" +} + +dtrace -qs /dev/stdin -x encoding=utf8 <<EOF +`outputstr "why must i do this"` +EOF + +dtrace -qs /dev/stdin -x encoding=ascii -x aggzoom <<EOF +`outputstr "i am not well"` +EOF + +dtrace -qs /dev/stdin -x encoding=utf8 -x aggzoom <<EOF +`outputstr "send help"` +EOF + diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.aggpackbanner.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.aggpackbanner.ksh.out new file mode 100644 index 0000000..a7eba38 --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.aggpackbanner.ksh.out @@ -0,0 +1,102 @@ + + + key min .------------------------------------------. max | count + 2 < 0 : ▂ ▂ ▂ ▂ ▂ ▂ : >= 40 | 6 + 3 < 0 : ▂ ▂ ▂ ▂ ▂ ▂ : >= 40 | 6 + 4 < 0 : ▂ ▂ ▂▂▂▂▂▂ ▂ : >= 40 | 9 + 5 < 0 : ▂ ▂▂ ▂ ▂ ▂ ▂ : >= 40 | 7 + 6 < 0 : ▂▂ ▂▂ ▂ ▂ ▂ : >= 40 | 7 + 7 < 0 : ▂ ▂ ▂ ▂ ▂ : >= 40 | 5 + + + key min .------------------------------------------. max | count + 2 < 0 : ▂ ▂ ▂ ▂ ▂▂▂▂ ▂▂▂▂▂ : >= 40 | 13 + 3 < 0 : ▂▂ ▂▂ ▂ ▂ ▂ ▂ : >= 40 | 8 + 4 < 0 : ▂ ▂▂ ▂ ▂ ▂ ▂▂▂▂ ▂ : >= 40 | 11 + 5 < 0 : ▂ ▂ ▂ ▂ ▂ ▂ : >= 40 | 6 + 6 < 0 : ▂ ▂ ▂ ▂ ▂ ▂ ▂ : >= 40 | 7 + 7 < 0 : ▂ ▂ ▂▂▂▂ ▂▂▂▂ ▂ : >= 40 | 11 + + + key min .------------------------------------------. max | count + 2 < 0 : █ : >= 40 | 1 + 3 < 0 : █ : >= 40 | 1 + 4 < 0 : █ : >= 40 | 1 + 5 < 0 : █ : >= 40 | 1 + 6 < 0 : █ : >= 40 | 1 + 7 < 0 : █ : >= 40 | 1 + + + key min .------------------------------------------. max | count + 2 < 0 : ▂▂▂▂▂ ▂▂▂▂ : >= 40 | 9 + 3 < 0 : ▃ ▃ ▃ ▃ : >= 40 | 4 + 4 < 0 : ▃ ▃ ▃ ▃ : >= 40 | 4 + 5 < 0 : ▃ ▃ ▃ ▃ : >= 40 | 4 + 6 < 0 : ▃ ▃ ▃ ▃ : >= 40 | 4 + 7 < 0 : ▂▂▂▂▂ ▂▂▂▂ : >= 40 | 9 + + + key min .------------------------------------------. max | count + 2 < 0 : ▂▂▂▂▂ ▂ ▂ ▂ ▂▂▂▂ : >= 40 | 12 + 3 < 0 : ▂ ▂ ▂ ▂ ▂ : >= 40 | 5 + 4 < 0 : ▂ ▂▂▂▂▂▂ ▂ ▂▂▂▂ : >= 40 | 12 + 5 < 0 : ▂ ▂ ▂ ▂ ▂ : >= 40 | 5 + 6 < 0 : ▂ ▂ ▂ ▂ ▂ ▂ : >= 40 | 6 + 7 < 0 : ▂ ▂ ▂ ▂ ▂▂▂▂ : >= 40 | 8 + + + + key min .------------------------------------------. max | count + 2 < 0 : X : >= 40 | 1 + 3 < 0 : X : >= 40 | 1 + 4 < 0 : X : >= 40 | 1 + 5 < 0 : X : >= 40 | 1 + 6 < 0 : X : >= 40 | 1 + 7 < 0 : X : >= 40 | 1 + + + key min .------------------------------------------. max | count + 2 < 0 : XX X X : >= 40 | 4 + 3 < 0 : X X XX XX : >= 40 | 6 + 4 < 0 : X X X XX X : >= 40 | 6 + 5 < 0 : XXXXXX X X : >= 40 | 8 + 6 < 0 : X X X X : >= 40 | 4 + 7 < 0 : X X X X : >= 40 | 4 + + + key min .------------------------------------------. max | count + 2 < 0 : X X XXXX XXXXX : >= 40 | 11 + 3 < 0 : XX X X X X : >= 40 | 6 + 4 < 0 : X X X X X X : >= 40 | 6 + 5 < 0 : X X X X X X : >= 40 | 6 + 6 < 0 : X XX X X X : >= 40 | 6 + 7 < 0 : X X XXXX X : >= 40 | 7 + + + key min .------------------------------------------. max | count + 2 < 0 : X X XXXXXX X X : >= 40 | 10 + 3 < 0 : X X X X X : >= 40 | 5 + 4 < 0 : X X XXXXX X X : >= 40 | 9 + 5 < 0 : X XX X X X X : >= 40 | 7 + 6 < 0 : XX XX X X X : >= 40 | 7 + 7 < 0 : X X XXXXXX XXXXXX XXXXXX : >= 40 | 20 + + + + key min .------------------------------------------. max | count + 2 < 0 : ████ ██████ █ █ █████ : >= 40 | 17 + 3 < 0 : █ █ ██ █ █ █ : >= 40 | 7 + 4 < 0 : ████ █████ █ █ █ █ █ : >= 40 | 14 + 5 < 0 : █ █ █ █ █ █ █ : >= 40 | 7 + 6 < 0 : █ █ █ █ ██ █ █ : >= 40 | 8 + 7 < 0 : ████ ██████ █ █ █████ : >= 40 | 17 + + + key min .------------------------------------------. max | count + 2 < 0 : █ █ ██████ █ █████ : >= 40 | 14 + 3 < 0 : █ █ █ █ █ █ : >= 40 | 6 + 4 < 0 : ██████ █████ █ █ █ : >= 40 | 14 + 5 < 0 : █ █ █ █ █████ : >= 40 | 9 + 6 < 0 : █ █ █ █ █ : >= 40 | 5 + 7 < 0 : █ █ ██████ ██████ █ : >= 40 | 15 + diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.aggpackzoom.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.aggpackzoom.d new file mode 100644 index 0000000..2f297e2 --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.aggpackzoom.d @@ -0,0 +1,43 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright (c) 2013 Joyent, Inc. All rights reserved. + */ + +#pragma D option encoding=ascii +#pragma D option quiet + +tick-1ms +/i++ < 30/ +{ + @[1] = lquantize(i, 0, 40, 1, 1000); + @[2] = lquantize(i, 0, 40, 1, 1000); + @[3] = lquantize(i, 0, 40, 1, 1000); +} + +tick-1ms +/i == 40/ +{ + @[1] = lquantize(0, 0, 40, 1, 1); + @[1] = lquantize(i, 0, 40, 1, 2000); + @[2] = lquantize(0, 0, 40, 1, 1); + @[2] = lquantize(i, 0, 40, 1, 2000); + @[3] = lquantize(0, 0, 40, 1, 1); + @[3] = lquantize(i, 0, 40, 1, 2000); + + printa(@); + setopt("aggpack"); + printa(@); + setopt("aggzoom"); + printa(@); + exit(0); +} diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.aggpackzoom.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.aggpackzoom.d.out new file mode 100644 index 0000000..a22a2a4 --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.aggpackzoom.d.out @@ -0,0 +1,149 @@ + + 1 + value ------------- Distribution ------------- count + < 0 | 0 + 0 | 1 + 1 |@ 1000 + 2 |@ 1000 + 3 |@ 1000 + 4 |@ 1000 + 5 |@ 1000 + 6 |@ 1000 + 7 |@ 1000 + 8 |@ 1000 + 9 |@ 1000 + 10 |@ 1000 + 11 |@ 1000 + 12 |@ 1000 + 13 |@ 1000 + 14 |@ 1000 + 15 |@ 1000 + 16 |@ 1000 + 17 |@ 1000 + 18 |@ 1000 + 19 |@ 1000 + 20 |@ 1000 + 21 |@ 1000 + 22 |@ 1000 + 23 |@ 1000 + 24 |@ 1000 + 25 |@ 1000 + 26 |@ 1000 + 27 |@ 1000 + 28 |@ 1000 + 29 |@ 1000 + 30 |@ 1000 + 31 | 0 + 32 | 0 + 33 | 0 + 34 | 0 + 35 | 0 + 36 | 0 + 37 | 0 + 38 | 0 + 39 | 0 + >= 40 |@@ 2000 + + 2 + value ------------- Distribution ------------- count + < 0 | 0 + 0 | 1 + 1 |@ 1000 + 2 |@ 1000 + 3 |@ 1000 + 4 |@ 1000 + 5 |@ 1000 + 6 |@ 1000 + 7 |@ 1000 + 8 |@ 1000 + 9 |@ 1000 + 10 |@ 1000 + 11 |@ 1000 + 12 |@ 1000 + 13 |@ 1000 + 14 |@ 1000 + 15 |@ 1000 + 16 |@ 1000 + 17 |@ 1000 + 18 |@ 1000 + 19 |@ 1000 + 20 |@ 1000 + 21 |@ 1000 + 22 |@ 1000 + 23 |@ 1000 + 24 |@ 1000 + 25 |@ 1000 + 26 |@ 1000 + 27 |@ 1000 + 28 |@ 1000 + 29 |@ 1000 + 30 |@ 1000 + 31 | 0 + 32 | 0 + 33 | 0 + 34 | 0 + 35 | 0 + 36 | 0 + 37 | 0 + 38 | 0 + 39 | 0 + >= 40 |@@ 2000 + + 3 + value ------------- Distribution ------------- count + < 0 | 0 + 0 | 1 + 1 |@ 1000 + 2 |@ 1000 + 3 |@ 1000 + 4 |@ 1000 + 5 |@ 1000 + 6 |@ 1000 + 7 |@ 1000 + 8 |@ 1000 + 9 |@ 1000 + 10 |@ 1000 + 11 |@ 1000 + 12 |@ 1000 + 13 |@ 1000 + 14 |@ 1000 + 15 |@ 1000 + 16 |@ 1000 + 17 |@ 1000 + 18 |@ 1000 + 19 |@ 1000 + 20 |@ 1000 + 21 |@ 1000 + 22 |@ 1000 + 23 |@ 1000 + 24 |@ 1000 + 25 |@ 1000 + 26 |@ 1000 + 27 |@ 1000 + 28 |@ 1000 + 29 |@ 1000 + 30 |@ 1000 + 31 | 0 + 32 | 0 + 33 | 0 + 34 | 0 + 35 | 0 + 36 | 0 + 37 | 0 + 38 | 0 + 39 | 0 + >= 40 |@@ 2000 + + + + key min .------------------------------------------. max | count + 1 < 0 : _______________________________ _: >= 40 | 32001 + 2 < 0 : _______________________________ _: >= 40 | 32001 + 3 < 0 : _______________________________ _: >= 40 | 32001 + + + key min .------------------------------------------. max | count + 1 < 0 : _xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx X: >= 40 | 32001 + 2 < 0 : _xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx X: >= 40 | 32001 + 3 < 0 : _xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx X: >= 40 | 32001 + diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.aggzoom.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.aggzoom.d new file mode 100644 index 0000000..f237d26 --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.aggzoom.d @@ -0,0 +1,35 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright (c) 2013 Joyent, Inc. All rights reserved. + */ + +#pragma D option encoding=ascii +#pragma D option quiet + +tick-1ms +/i++ < 90/ +{ + @ = lquantize(i, 0, 100, 1, 1000); +} + +tick-1ms +/i == 100/ +{ + @ = lquantize(i++, 0, 100, 1, 2000); + @ = lquantize(i++, 0, 100, 1, 3000); + + printa(@); + setopt("aggzoom"); + printa(@); + exit(0); +} diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.aggzoom.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.aggzoom.d.out new file mode 100644 index 0000000..acddf7f --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.aggzoom.d.out @@ -0,0 +1,211 @@ + + + value ------------- Distribution ------------- count + 0 | 0 + 1 | 1000 + 2 | 1000 + 3 | 1000 + 4 | 1000 + 5 | 1000 + 6 | 1000 + 7 | 1000 + 8 | 1000 + 9 | 1000 + 10 | 1000 + 11 | 1000 + 12 | 1000 + 13 | 1000 + 14 | 1000 + 15 | 1000 + 16 | 1000 + 17 | 1000 + 18 | 1000 + 19 | 1000 + 20 | 1000 + 21 | 1000 + 22 | 1000 + 23 | 1000 + 24 | 1000 + 25 | 1000 + 26 | 1000 + 27 | 1000 + 28 | 1000 + 29 | 1000 + 30 | 1000 + 31 | 1000 + 32 | 1000 + 33 | 1000 + 34 | 1000 + 35 | 1000 + 36 | 1000 + 37 | 1000 + 38 | 1000 + 39 | 1000 + 40 | 1000 + 41 | 1000 + 42 | 1000 + 43 | 1000 + 44 | 1000 + 45 | 1000 + 46 | 1000 + 47 | 1000 + 48 | 1000 + 49 | 1000 + 50 | 1000 + 51 | 1000 + 52 | 1000 + 53 | 1000 + 54 | 1000 + 55 | 1000 + 56 | 1000 + 57 | 1000 + 58 | 1000 + 59 | 1000 + 60 | 1000 + 61 | 1000 + 62 | 1000 + 63 | 1000 + 64 | 1000 + 65 | 1000 + 66 | 1000 + 67 | 1000 + 68 | 1000 + 69 | 1000 + 70 | 1000 + 71 | 1000 + 72 | 1000 + 73 | 1000 + 74 | 1000 + 75 | 1000 + 76 | 1000 + 77 | 1000 + 78 | 1000 + 79 | 1000 + 80 | 1000 + 81 | 1000 + 82 | 1000 + 83 | 1000 + 84 | 1000 + 85 | 1000 + 86 | 1000 + 87 | 1000 + 88 | 1000 + 89 | 1000 + 90 | 1000 + 91 | 0 + 92 | 0 + 93 | 0 + 94 | 0 + 95 | 0 + 96 | 0 + 97 | 0 + 98 | 0 + 99 | 0 + >= 100 |@@ 5000 + + + + value ------------- Distribution ------------- count + 0 | 0 + 1 |@@@@@@@@ 1000 + 2 |@@@@@@@@ 1000 + 3 |@@@@@@@@ 1000 + 4 |@@@@@@@@ 1000 + 5 |@@@@@@@@ 1000 + 6 |@@@@@@@@ 1000 + 7 |@@@@@@@@ 1000 + 8 |@@@@@@@@ 1000 + 9 |@@@@@@@@ 1000 + 10 |@@@@@@@@ 1000 + 11 |@@@@@@@@ 1000 + 12 |@@@@@@@@ 1000 + 13 |@@@@@@@@ 1000 + 14 |@@@@@@@@ 1000 + 15 |@@@@@@@@ 1000 + 16 |@@@@@@@@ 1000 + 17 |@@@@@@@@ 1000 + 18 |@@@@@@@@ 1000 + 19 |@@@@@@@@ 1000 + 20 |@@@@@@@@ 1000 + 21 |@@@@@@@@ 1000 + 22 |@@@@@@@@ 1000 + 23 |@@@@@@@@ 1000 + 24 |@@@@@@@@ 1000 + 25 |@@@@@@@@ 1000 + 26 |@@@@@@@@ 1000 + 27 |@@@@@@@@ 1000 + 28 |@@@@@@@@ 1000 + 29 |@@@@@@@@ 1000 + 30 |@@@@@@@@ 1000 + 31 |@@@@@@@@ 1000 + 32 |@@@@@@@@ 1000 + 33 |@@@@@@@@ 1000 + 34 |@@@@@@@@ 1000 + 35 |@@@@@@@@ 1000 + 36 |@@@@@@@@ 1000 + 37 |@@@@@@@@ 1000 + 38 |@@@@@@@@ 1000 + 39 |@@@@@@@@ 1000 + 40 |@@@@@@@@ 1000 + 41 |@@@@@@@@ 1000 + 42 |@@@@@@@@ 1000 + 43 |@@@@@@@@ 1000 + 44 |@@@@@@@@ 1000 + 45 |@@@@@@@@ 1000 + 46 |@@@@@@@@ 1000 + 47 |@@@@@@@@ 1000 + 48 |@@@@@@@@ 1000 + 49 |@@@@@@@@ 1000 + 50 |@@@@@@@@ 1000 + 51 |@@@@@@@@ 1000 + 52 |@@@@@@@@ 1000 + 53 |@@@@@@@@ 1000 + 54 |@@@@@@@@ 1000 + 55 |@@@@@@@@ 1000 + 56 |@@@@@@@@ 1000 + 57 |@@@@@@@@ 1000 + 58 |@@@@@@@@ 1000 + 59 |@@@@@@@@ 1000 + 60 |@@@@@@@@ 1000 + 61 |@@@@@@@@ 1000 + 62 |@@@@@@@@ 1000 + 63 |@@@@@@@@ 1000 + 64 |@@@@@@@@ 1000 + 65 |@@@@@@@@ 1000 + 66 |@@@@@@@@ 1000 + 67 |@@@@@@@@ 1000 + 68 |@@@@@@@@ 1000 + 69 |@@@@@@@@ 1000 + 70 |@@@@@@@@ 1000 + 71 |@@@@@@@@ 1000 + 72 |@@@@@@@@ 1000 + 73 |@@@@@@@@ 1000 + 74 |@@@@@@@@ 1000 + 75 |@@@@@@@@ 1000 + 76 |@@@@@@@@ 1000 + 77 |@@@@@@@@ 1000 + 78 |@@@@@@@@ 1000 + 79 |@@@@@@@@ 1000 + 80 |@@@@@@@@ 1000 + 81 |@@@@@@@@ 1000 + 82 |@@@@@@@@ 1000 + 83 |@@@@@@@@ 1000 + 84 |@@@@@@@@ 1000 + 85 |@@@@@@@@ 1000 + 86 |@@@@@@@@ 1000 + 87 |@@@@@@@@ 1000 + 88 |@@@@@@@@ 1000 + 89 |@@@@@@@@ 1000 + 90 |@@@@@@@@ 1000 + 91 | 0 + 92 | 0 + 93 | 0 + 94 | 0 + 95 | 0 + 96 | 0 + 97 | 0 + 98 | 0 + 99 | 0 + >= 100 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 5000 + + diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.subr.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.subr.d index d508596..9b02e98 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.subr.d +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.subr.d @@ -22,6 +22,7 @@ /* * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright (c) 2012, Joyent, Inc. All rights reserved. */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -97,6 +98,9 @@ INTFUNC(ntohll(0x1234567890abcdefL)) STRFUNC(inet_ntoa((ipaddr_t *)alloca(sizeof (ipaddr_t)))) STRFUNC(inet_ntoa6((in6_addr_t *)alloca(sizeof (in6_addr_t)))) STRFUNC(inet_ntop(AF_INET, (void *)alloca(sizeof (ipaddr_t)))) +INTFUNC(getf(0)) +INTFUNC(strtoll("0x12EE5D5", 16)) +STRFUNC(json("{\"systemtap\": false}", "systemtap")) BEGIN /subr == DIF_SUBR_MAX + 1/ diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/json/tst.general.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/json/tst.general.d new file mode 100644 index 0000000..4600811 --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/json/tst.general.d @@ -0,0 +1,179 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2012, Joyent, Inc. All rights reserved. + */ + +/* + * General functional tests of JSON parser for json(). + */ + +#pragma D option quiet +#pragma D option strsize=1k + +#define TST(name) \ + printf("\ntst |%s|\n", name) +#define IN2(vala, valb) \ + in = strjoin(vala, valb); \ + printf("in |%s|\n", in) +#define IN(val) \ + in = val; \ + printf("in |%s|\n", in) +#define SEL(ss) \ + out = json(in, ss); \ + printf("sel |%s|\nout |%s|\n", ss, \ + out != NULL ? out : "<NULL>") + +BEGIN +{ + TST("empty array"); + IN("[]"); + SEL("0"); + + TST("one-element array: integer"); + IN("[1]"); + SEL("0"); + SEL("1"); + SEL("100"); + SEL("-1"); + + TST("one-element array: hex integer (not in spec, not supported)"); + IN("[0x1000]"); + SEL("0"); + + TST("one-element array: float"); + IN("[1.5001]"); + SEL("0"); + + TST("one-element array: float + exponent"); + IN("[16.3e10]"); + SEL("0"); + + TST("one-element array: integer + whitespace"); + IN("[ \t 5\t]"); + SEL("0"); + + TST("one-element array: integer + exponent + whitespace"); + IN("[ \t \t 16E10 \t ]"); + SEL("0"); + + TST("one-element array: string"); + IN("[\"alpha\"]"); + SEL("0"); + + TST("alternative first-element indexing"); + IN("[1,5,10,15,20]"); + SEL("[0]"); + SEL("[3]"); + SEL("[4]"); + SEL("[5]"); + + TST("one-element array: object"); + IN("[ { \"first\": true, \"second\": false }]"); + SEL("0.first"); + SEL("0.second"); + SEL("0.third"); + + TST("many-element array: integers"); + IN("[0,1,1,2,3,5,8,13,21,34,55,89,144,233,377]"); + SEL("10"); /* F(10) = 55 */ + SEL("14"); /* F(14) = 377 */ + SEL("19"); + + TST("many-element array: multiple types"); + IN2("[\"string\",32,true,{\"a\":9,\"b\":false},100.3e10,false,200.5,", + "{\"key\":\"val\"},null]"); + SEL("0"); + SEL("0.notobject"); + SEL("1"); + SEL("2"); + SEL("3"); + SEL("3.a"); + SEL("3.b"); + SEL("3.c"); + SEL("4"); + SEL("5"); + SEL("6"); + SEL("7"); + SEL("7.key"); + SEL("7.key.notobject"); + SEL("7.nonexist"); + SEL("8"); + SEL("9"); + + TST("many-element array: multiple types + whitespace"); + IN2("\n[\t\"string\" ,\t32 , true\t,\t {\"a\": 9,\t\"b\": false},\t\t", + "100.3e10, false, 200.5,{\"key\" \t:\n \"val\"},\t\t null ]\t\t"); + SEL("0"); + SEL("0.notobject"); + SEL("1"); + SEL("2"); + SEL("3"); + SEL("3.a"); + SEL("3.b"); + SEL("3.c"); + SEL("4"); + SEL("5"); + SEL("6"); + SEL("7"); + SEL("7.key"); + SEL("7.key.notobject"); + SEL("7.nonexist"); + SEL("8"); + SEL("9"); + + TST("two-element array: various string escape codes"); + IN2("[\"abcd \\\" \\\\ \\/ \\b \\f \\n \\r \\t \\u0000 \\uf00F \", ", + "\"final\"]"); + SEL("0"); + SEL("1"); + + TST("three-element array: broken escape code"); + IN("[\"fine here\", \"dodgey \\u00AZ\", \"wont get here\"]"); + SEL("0"); + SEL("1"); + SEL("2"); + + TST("nested objects"); + IN2("{ \"top\": { \"mid\" : { \"legs\": \"feet\" }, \"number\": 9, ", + "\"array\":[0,1,{\"a\":true,\"bb\":[1,2,false,{\"x\":\"yz\"}]}]}}"); + SEL("top"); + SEL("fargo"); + SEL("top.mid"); + SEL("top.centre"); + SEL("top.mid.legs"); + SEL("top.mid.number"); + SEL("top.mid.array"); + SEL("top.number"); + SEL("top.array"); + SEL("top.array[0]"); + SEL("top.array[1]"); + SEL("top.array[2]"); + SEL("top.array[2].a"); + SEL("top.array[2].b"); + SEL("top.array[2].bb"); + SEL("top.array[2].bb[0]"); + SEL("top.array[2].bb[1]"); + SEL("top.array[2].bb[2]"); + SEL("top.array[2].bb[3]"); + SEL("top.array[2].bb[3].x"); + SEL("top.array[2].bb[3].x.nofurther"); + SEL("top.array[2].bb[4]"); + SEL("top.array[3]"); + + exit(0); +} + +ERROR +{ + exit(1); +} diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/json/tst.general.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/json/tst.general.d.out new file mode 100644 index 0000000..a857ab9 --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/json/tst.general.d.out @@ -0,0 +1,218 @@ + +tst |empty array| +in |[]| +sel |0| +out |<NULL>| + +tst |one-element array: integer| +in |[1]| +sel |0| +out |1| +sel |1| +out |<NULL>| +sel |100| +out |<NULL>| +sel |-1| +out |<NULL>| + +tst |one-element array: hex integer (not in spec, not supported)| +in |[0x1000]| +sel |0| +out |<NULL>| + +tst |one-element array: float| +in |[1.5001]| +sel |0| +out |1.5001| + +tst |one-element array: float + exponent| +in |[16.3e10]| +sel |0| +out |16.3e10| + +tst |one-element array: integer + whitespace| +in |[ 5 ]| +sel |0| +out |5| + +tst |one-element array: integer + exponent + whitespace| +in |[ 16E10 ]| +sel |0| +out |16E10| + +tst |one-element array: string| +in |["alpha"]| +sel |0| +out |alpha| + +tst |alternative first-element indexing| +in |[1,5,10,15,20]| +sel |[0]| +out |1| +sel |[3]| +out |15| +sel |[4]| +out |20| +sel |[5]| +out |<NULL>| + +tst |one-element array: object| +in |[ { "first": true, "second": false }]| +sel |0.first| +out |true| +sel |0.second| +out |false| +sel |0.third| +out |<NULL>| + +tst |many-element array: integers| +in |[0,1,1,2,3,5,8,13,21,34,55,89,144,233,377]| +sel |10| +out |55| +sel |14| +out |377| +sel |19| +out |<NULL>| + +tst |many-element array: multiple types| +in |["string",32,true,{"a":9,"b":false},100.3e10,false,200.5,{"key":"val"},null]| +sel |0| +out |string| +sel |0.notobject| +out |<NULL>| +sel |1| +out |32| +sel |2| +out |true| +sel |3| +out |{"a":9,"b":false}| +sel |3.a| +out |9| +sel |3.b| +out |false| +sel |3.c| +out |<NULL>| +sel |4| +out |100.3e10| +sel |5| +out |false| +sel |6| +out |200.5| +sel |7| +out |{"key":"val"}| +sel |7.key| +out |val| +sel |7.key.notobject| +out |<NULL>| +sel |7.nonexist| +out |<NULL>| +sel |8| +out |null| +sel |9| +out |<NULL>| + +tst |many-element array: multiple types + whitespace| +in | +[ "string" , 32 , true , {"a": 9, "b": false}, 100.3e10, false, 200.5,{"key" : + "val"}, null ] | +sel |0| +out |string| +sel |0.notobject| +out |<NULL>| +sel |1| +out |32| +sel |2| +out |true| +sel |3| +out |{"a": 9, "b": false}| +sel |3.a| +out |9| +sel |3.b| +out |false| +sel |3.c| +out |<NULL>| +sel |4| +out |100.3e10| +sel |5| +out |false| +sel |6| +out |200.5| +sel |7| +out |{"key" : + "val"}| +sel |7.key| +out |val| +sel |7.key.notobject| +out |<NULL>| +sel |7.nonexist| +out |<NULL>| +sel |8| +out |null| +sel |9| +out |<NULL>| + +tst |two-element array: various string escape codes| +in |["abcd \" \\ \/ \b \f \n \r \t \u0000 \uf00F ", "final"]| +sel |0| +out |abcd \" \\ \/ \b \f \n \r \t \u0000 \uf00F | +sel |1| +out |final| + +tst |three-element array: broken escape code| +in |["fine here", "dodgey \u00AZ", "wont get here"]| +sel |0| +out |fine here| +sel |1| +out |<NULL>| +sel |2| +out |<NULL>| + +tst |nested objects| +in |{ "top": { "mid" : { "legs": "feet" }, "number": 9, "array":[0,1,{"a":true,"bb":[1,2,false,{"x":"yz"}]}]}}| +sel |top| +out |{ "mid" : { "legs": "feet" }, "number": 9, "array":[0,1,{"a":true,"bb":[1,2,false,{"x":"yz"}]}]}| +sel |fargo| +out |<NULL>| +sel |top.mid| +out |{ "legs": "feet" }| +sel |top.centre| +out |<NULL>| +sel |top.mid.legs| +out |feet| +sel |top.mid.number| +out |<NULL>| +sel |top.mid.array| +out |<NULL>| +sel |top.number| +out |9| +sel |top.array| +out |[0,1,{"a":true,"bb":[1,2,false,{"x":"yz"}]}]| +sel |top.array[0]| +out |0| +sel |top.array[1]| +out |1| +sel |top.array[2]| +out |{"a":true,"bb":[1,2,false,{"x":"yz"}]}| +sel |top.array[2].a| +out |true| +sel |top.array[2].b| +out |<NULL>| +sel |top.array[2].bb| +out |[1,2,false,{"x":"yz"}]| +sel |top.array[2].bb[0]| +out |1| +sel |top.array[2].bb[1]| +out |2| +sel |top.array[2].bb[2]| +out |false| +sel |top.array[2].bb[3]| +out |{"x":"yz"}| +sel |top.array[2].bb[3].x| +out |yz| +sel |top.array[2].bb[3].x.nofurther| +out |<NULL>| +sel |top.array[2].bb[4]| +out |<NULL>| +sel |top.array[3]| +out |<NULL>| + diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/json/tst.strsize.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/json/tst.strsize.d new file mode 100644 index 0000000..6aa50b9 --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/json/tst.strsize.d @@ -0,0 +1,51 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2012, Joyent, Inc. All rights reserved. + */ + +/* + * ASSERTION: + * json() run time must be bounded above by strsize. This test makes strsize + * small and deliberately overflows it to prove we bail and return NULL in + * the event that we run off the end of the string. + * + */ + +#pragma D option quiet +#pragma D option strsize=18 + +BEGIN +{ + in = "{\"a\": 1024}"; /* length == 19 */ + out = json(in, "a"); + printf("|%s|\n%s\n\n", in, out != NULL ? out : "<NULL>"); + + in = "{\"a\": 1024}"; /* length == 11 */ + out = json(in, "a"); + printf("|%s|\n%s\n\n", in, out != NULL ? out : "<NULL>"); + + in = "{\"a\":false,\"b\":true}"; /* length == 20 */ + out = json(in, "b"); + printf("|%s|\n%s\n\n", in, out != NULL ? out : "<NULL>"); + + in = "{\"a\":false,\"b\":20}"; /* length == 18 */ + out = json(in, "b"); + printf("|%s|\n%s\n\n", in, out != NULL ? out : "<NULL>"); + + exit(0); +} + +ERROR +{ + exit(1); +} diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/json/tst.strsize.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/json/tst.strsize.d.out new file mode 100644 index 0000000..7f1d79b --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/json/tst.strsize.d.out @@ -0,0 +1,13 @@ +|{"a": 1024| +<NULL> + +|{"a": 1024}| +1024 + +|{"a":false,"b":tru| +<NULL> + +|{"a":false,"b":20}| +20 + + diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/json/tst.usdt.c b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/json/tst.usdt.c new file mode 100644 index 0000000..307106d --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/json/tst.usdt.c @@ -0,0 +1,61 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2012 (c), Joyent, Inc. All rights reserved. + */ + +#include <sys/sdt.h> +#include "usdt.h" + +#define FMT "{" \ + " \"sizes\": [ \"first\", 2, %f ]," \ + " \"index\": %d," \ + " \"facts\": {" \ + " \"odd\": \"%s\"," \ + " \"even\": \"%s\"" \ + " }," \ + " \"action\": \"%s\"" \ + "}\n" + +int +waiting(volatile int *a) +{ + return (*a); +} + +int +main(int argc, char **argv) +{ + volatile int a = 0; + int idx; + double size = 250.5; + + while (waiting(&a) == 0) + continue; + + for (idx = 0; idx < 10; idx++) { + char *odd, *even, *json, *action; + + size *= 1.78; + odd = idx % 2 == 1 ? "true" : "false"; + even = idx % 2 == 0 ? "true" : "false"; + action = idx == 7 ? "ignore" : "print"; + + asprintf(&json, FMT, size, idx, odd, even, action); + BUNYAN_FAKE_LOG_DEBUG(json); + free(json); + } + + BUNYAN_FAKE_LOG_DEBUG("{\"finished\": true}"); + + return (0); +} diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/json/tst.usdt.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/json/tst.usdt.d new file mode 100644 index 0000000..f0fbdd5 --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/json/tst.usdt.d @@ -0,0 +1,65 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright (c) 2012, Joyent, Inc. All rights reserved. + */ + +#pragma D option strsize=4k +#pragma D option quiet +#pragma D option destructive + +/* + * This test reads a JSON string from a USDT probe, roughly simulating the + * primary motivating use case for the json() subroutine: filtering + * JSON-formatted log messages from a logging subsystem like node-bunyan. + */ + +pid$1:a.out:waiting:entry +{ + this->value = (int *)alloca(sizeof (int)); + *this->value = 1; + copyout(this->value, arg0, sizeof (int)); +} + +bunyan*$1:::log-* +{ + this->j = copyinstr(arg0); +} + +bunyan*$1:::log-* +/json(this->j, "finished") == NULL && json(this->j, "action") != "ignore"/ +{ + this->index = strtoll(json(this->j, "index")); + this->size = json(this->j, "sizes[2]"); + this->odd = json(this->j, "facts.odd"); + this->even = json(this->j, "facts.even"); + printf("[%d] sz %s odd %s even %s\n", this->index, this->size, + this->odd, this->even); +} + +bunyan*$1:::log-* +/json(this->j, "finished") != NULL/ +{ + printf("FINISHED!\n"); + exit(0); +} + +tick-10s +{ + printf("ERROR: Timed out before finish message!\n"); + exit(1); +} + +ERROR +{ + exit(1); +} diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/json/tst.usdt.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/json/tst.usdt.d.out new file mode 100644 index 0000000..c7f58bb --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/json/tst.usdt.d.out @@ -0,0 +1,11 @@ +[0] sz 445.890000 odd false even true +[1] sz 793.684200 odd true even false +[2] sz 1412.757876 odd false even true +[3] sz 2514.709019 odd true even false +[4] sz 4476.182054 odd false even true +[5] sz 7967.604057 odd true even false +[6] sz 14182.335221 odd false even true +[8] sz 44935.310914 odd false even true +[9] sz 79984.853427 odd true even false +FINISHED! + diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/json/usdt.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/json/usdt.d new file mode 100644 index 0000000..1a4fc87 --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/json/usdt.d @@ -0,0 +1,27 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2012, Joyent, Inc. All rights reserved. + */ + +/* + * Sets up a fake node-bunyan-like USDT provider for use from C. + */ + +provider bunyan_fake { + probe log__trace(char *msg); + probe log__debug(char *msg); + probe log__info(char *msg); + probe log__warn(char *msg); + probe log__error(char *msg); + probe log__fatal(char *msg); +}; diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/privs/tst.fds.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/privs/tst.fds.ksh new file mode 100644 index 0000000..a5aa271 --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/privs/tst.fds.ksh @@ -0,0 +1,91 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright (c) 2012, Joyent, Inc. All rights reserved. +# + +tmpin=/tmp/tst.fds.$$.d +tmpout1=/tmp/tst.fds.$$.out1 +tmpout2=/tmp/tst.fds.$$.out2 + +cat > $tmpin <<EOF +#define DUMPFIELD(fd, fmt, field) \ + errmsg = "could not dump field"; \ + printf("%d: field =fmt\n", fd, fds[fd].field); + +/* + * Note that we are explicitly not looking at fi_mount -- it (by design) does + * not work if not running with kernel permissions. + */ +#define DUMP(fd) \ + DUMPFIELD(fd, %s, fi_name); \ + DUMPFIELD(fd, %s, fi_dirname); \ + DUMPFIELD(fd, %s, fi_pathname); \ + DUMPFIELD(fd, %d, fi_offset); \ + DUMPFIELD(fd, %s, fi_fs); \ + DUMPFIELD(fd, %o, fi_oflags); + +BEGIN +{ + DUMP(0); + DUMP(1); + DUMP(2); + DUMP(3); + DUMP(4); + exit(0); +} + +ERROR +{ + printf("error: %s\n", errmsg); + exit(1); +} +EOF + +# +# First, with all privs +# +/usr/sbin/dtrace -q -Cs /dev/stdin < $tmpin > $tmpout2 +mv $tmpout2 $tmpout1 + +# +# And now with only dtrace_proc and dtrace_user -- the output should be +# identical. +# +ppriv -s A=basic,dtrace_proc,dtrace_user $$ + +/usr/sbin/dtrace -q -Cs /dev/stdin < $tmpin > $tmpout2 + +echo ">>> $tmpout1" +cat $tmpout1 + +echo ">>> $tmpout2" +cat $tmpout2 + +rval=0 + +if ! cmp $tmpout1 $tmpout2 ; then + rval=1 +fi + +rm $tmpout1 $tmpout2 $tmpin +exit $rval diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/privs/tst.func_access.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/privs/tst.func_access.ksh index ae4934c..da9bb4c 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/privs/tst.func_access.ksh +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/privs/tst.func_access.ksh @@ -22,8 +22,8 @@ # # Copyright 2006 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. +# Copyright (c) 2012, Joyent, Inc. All rights reserved. # -#ident "%Z%%M% %I% %E% SMI" ppriv -s A=basic,dtrace_proc,dtrace_user $$ @@ -31,7 +31,7 @@ ppriv -s A=basic,dtrace_proc,dtrace_user $$ BEGIN { errorcount = 0; - expected_errorcount = 23; + expected_errorcount = 27; } BEGIN { trace(mutex_owned(&`pidlock)); } @@ -55,6 +55,8 @@ BEGIN { trace(strtok(`initname, "/")); } BEGIN { trace(strtok(NULL, "/")); } BEGIN { trace(strtok("foo/bar", `initname)); } BEGIN { trace(strtok(NULL, `initname)); } +BEGIN { trace(strtoll(`initname)); } +BEGIN { trace(strtoll(`initname, 10)); } BEGIN { trace(substr(`initname, 2, 3)); } BEGIN { trace(ddi_pathname(`top_devinfo, 1)); } @@ -63,6 +65,9 @@ BEGIN { trace(strjoin("foo", `initname)); } BEGIN { trace(dirname(`initname)); } BEGIN { trace(cleanpath(`initname)); } +BEGIN { j = "{\"/sbin/init\":\"uh oh\"}"; trace(json(j, `initname)); } +BEGIN { trace(json(`initname, "x")); } + ERROR { errorcount++; } diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/privs/tst.getf.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/privs/tst.getf.ksh new file mode 100644 index 0000000..7dbb83f --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/privs/tst.getf.ksh @@ -0,0 +1,98 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright (c) 2012, Joyent, Inc. All rights reserved. +# + +ppriv -s A=basic,dtrace_proc,dtrace_user $$ + +/usr/sbin/dtrace -q -Cs /dev/stdin <<EOF + +#define CANREAD(field) \ + BEGIN { this->fp = getf(0); errmsg = "can't read field"; \ + printf("field: "); trace(this->fp->field); printf("\n"); } + +#define CANTREAD(field) \ + BEGIN { errmsg = ""; this->fp = getf(0); trace(this->fp->field); \ + printf("\nable to successfully read field!"); exit(1); } + +CANREAD(f_flag) +CANREAD(f_flag2) +CANREAD(f_vnode) +CANREAD(f_offset) +CANREAD(f_cred) +CANREAD(f_audit_data) +CANREAD(f_count) + +/* + * We can potentially read parts of our cred, but we can't dereference + * through cr_zone. + */ +CANTREAD(f_cred->cr_zone->zone_id) + +CANREAD(f_vnode->v_path) +CANREAD(f_vnode->v_op) +CANREAD(f_vnode->v_op->vnop_name) + +CANTREAD(f_vnode->v_flag) +CANTREAD(f_vnode->v_count) +CANTREAD(f_vnode->v_pages) +CANTREAD(f_vnode->v_type) +CANTREAD(f_vnode->v_vfsmountedhere) +CANTREAD(f_vnode->v_op->vop_open) + +BEGIN +{ + errmsg = ""; + this->fp = getf(0); + this->fp2 = getf(1); + + trace(this->fp->f_vnode); + printf("\nable to successfully read this->fp!"); + exit(1); +} + +BEGIN +{ + errmsg = ""; + this->fp = getf(0); +} + +BEGIN +{ + trace(this->fp->f_vnode); + printf("\nable to successfully read this->fp from prior clause!"); +} + +BEGIN +{ + exit(0); +} + +ERROR +/errmsg != ""/ +{ + printf("fatal error: %s", errmsg); + exit(1); +} + +EOF diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/privs/tst.procpriv.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/privs/tst.procpriv.ksh new file mode 100644 index 0000000..7022566 --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/privs/tst.procpriv.ksh @@ -0,0 +1,138 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright (c) 2012, Joyent, Inc. All rights reserved. +# + +ppriv -s A=basic,dtrace_proc,dtrace_user $$ + +# +# When we have dtrace_proc (but lack dtrace_kernel), we expect to be able to +# read certain curpsinfo/curlwpsinfo/curcpu fields even though they require +# reading in-kernel state. However, there are other fields in these translated +# structures that we know we shouldn't be able to read, as they require reading +# in-kernel state that we cannot read with only dtrace_proc. Finally, there +# are a few fields that we may or may not be able to read depending on the +# specifics of context. This test therefore asserts that we can read what we +# think we should be able to, that we can't read what we think we shouldn't be +# able to, and (for purposes of completeness) that we are indifferent about +# what we cannot assert one way or the other. +# +/usr/sbin/dtrace -q -Cs /dev/stdin <<EOF + +#define CANREAD(what, field) \ + BEGIN { errmsg = "can't read field from what"; printf("field: "); \ + trace(what->field); printf("\n"); } + +#define CANTREAD(what, field) \ + BEGIN { errmsg = ""; trace(what->field); \ + printf("\nable to successfully read field from what!"); exit(1); } + +#define MIGHTREAD(what, field) \ + BEGIN { errmsg = ""; printf("field: "); trace(what->field); printf("\n"); } + +#define CANREADVAR(vname) \ + BEGIN { errmsg = "can't read vname"; printf("vname: "); \ + trace(vname); printf("\n"); } + +#define CANTREADVAR(vname) \ + BEGIN { errmsg = ""; trace(vname); \ + printf("\nable to successfully read vname!"); exit(1); } + +#define MIGHTREADVAR(vname) \ + BEGIN { errmsg = ""; printf("vname: "); trace(vname); printf("\n"); } + +CANREAD(curpsinfo, pr_pid) +CANREAD(curpsinfo, pr_nlwp) +CANREAD(curpsinfo, pr_ppid) +CANREAD(curpsinfo, pr_uid) +CANREAD(curpsinfo, pr_euid) +CANREAD(curpsinfo, pr_gid) +CANREAD(curpsinfo, pr_egid) +CANREAD(curpsinfo, pr_addr) +CANREAD(curpsinfo, pr_start) +CANREAD(curpsinfo, pr_fname) +CANREAD(curpsinfo, pr_psargs) +CANREAD(curpsinfo, pr_argc) +CANREAD(curpsinfo, pr_argv) +CANREAD(curpsinfo, pr_envp) +CANREAD(curpsinfo, pr_dmodel) + +/* + * If our p_pgidp points to the same pid structure as our p_pidp, we will + * be able to read pr_pgid -- but we won't if not. + */ +MIGHTREAD(curpsinfo, pr_pgid) + +CANTREAD(curpsinfo, pr_sid) +CANTREAD(curpsinfo, pr_ttydev) +CANTREAD(curpsinfo, pr_projid) +CANTREAD(curpsinfo, pr_zoneid) +CANTREAD(curpsinfo, pr_contract) + +CANREAD(curlwpsinfo, pr_flag) +CANREAD(curlwpsinfo, pr_lwpid) +CANREAD(curlwpsinfo, pr_addr) +CANREAD(curlwpsinfo, pr_wchan) +CANREAD(curlwpsinfo, pr_stype) +CANREAD(curlwpsinfo, pr_state) +CANREAD(curlwpsinfo, pr_sname) +CANREAD(curlwpsinfo, pr_syscall) +CANREAD(curlwpsinfo, pr_pri) +CANREAD(curlwpsinfo, pr_onpro) +CANREAD(curlwpsinfo, pr_bindpro) +CANREAD(curlwpsinfo, pr_bindpset) + +CANTREAD(curlwpsinfo, pr_clname) +CANTREAD(curlwpsinfo, pr_lgrp) + +CANREAD(curcpu, cpu_id) + +CANTREAD(curcpu, cpu_pset) +CANTREAD(curcpu, cpu_chip) +CANTREAD(curcpu, cpu_lgrp) +CANTREAD(curcpu, cpu_info) + +/* + * We cannot assert one thing or another about the variable "root": for those + * with only dtrace_proc, it will be readable in the global but not readable in + * the non-global. + */ +MIGHTREADVAR(root) + +CANREADVAR(cpu) +CANTREADVAR(pset) +CANTREADVAR(cwd) +CANTREADVAR(chip) +CANTREADVAR(lgrp) + +BEGIN +{ + exit(0); +} + +ERROR +/errmsg != ""/ +{ + printf("fatal error: %s", errmsg); + exit(1); +} diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/privs/tst.providers.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/privs/tst.providers.ksh new file mode 100644 index 0000000..94c3722 --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/privs/tst.providers.ksh @@ -0,0 +1,126 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright (c) 2012, Joyent, Inc. All rights reserved. +# + +# +# First, make sure that we can successfully enable the io provider +# +if ! dtrace -P io -n BEGIN'{exit(0)}' > /dev/null 2>&1 ; then + echo failed to enable io provider with full privs + exit 1 +fi + +ppriv -s A=basic,dtrace_proc,dtrace_user $$ + +# +# Now make sure that we cannot enable the io provider with reduced privs +# +if ! dtrace -x errtags -P io -n BEGIN'{exit(1)}' 2>&1 | \ + grep D_PDESC_ZERO > /dev/null 2>&1 ; then + echo successfully enabled the io provider with reduced privs + exit 1 +fi + +# +# Keeping our reduced privs, we want to assure that we can see every provider +# that we think we should be able to see -- and that we can see curpsinfo +# state but can't otherwise see arguments. +# +/usr/sbin/dtrace -wq -Cs /dev/stdin <<EOF + +int seen[string]; +int err; + +#define CANENABLE(provider) \ +provider::: \ +/err == 0 && progenyof(\$pid) && !seen["provider"]/ \ +{ \ + trace(arg0); \ + printf("\nsuccessful trace of arg0 in %s:%s:%s:%s\n", \ + probeprov, probemod, probefunc, probename); \ + exit(++err); \ +} \ + \ +provider::: \ +/progenyof(\$pid)/ \ +{ \ + seen["provider"]++; \ +} \ + \ +provider::: \ +/progenyof(\$pid)/ \ +{ \ + errstr = "provider"; \ + this->ignore = stringof(curpsinfo->pr_psargs); \ + errstr = ""; \ +} \ + \ +END \ +/err == 0 && !seen["provider"]/ \ +{ \ + printf("no probes from provider\n"); \ + exit(++err); \ +} \ + \ +END \ +/err == 0/ \ +{ \ + printf("saw %d probes from provider\n", seen["provider"]); \ +} + +CANENABLE(proc) +CANENABLE(sched) +CANENABLE(vminfo) +CANENABLE(sysinfo) + +BEGIN +{ + /* + * We'll kick off a system of a do-nothing command -- which should be + * enough to kick proc, sched, vminfo and sysinfo probes. + */ + system("echo > /dev/null"); +} + +ERROR +/err == 0 && errstr != ""/ +{ + printf("fatal error: couldn't read curpsinfo->pr_psargs in "); + printf("%s-provided probe\n", errstr); + exit(++err); +} + +proc:::exit +/progenyof(\$pid)/ +{ + exit(0); +} + +tick-10ms +/i++ > 500/ +{ + printf("exit probe did not seem to fire\n"); + exit(++err); +} +EOF diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/strtoll/err.BaseTooLarge.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/strtoll/err.BaseTooLarge.d new file mode 100644 index 0000000..4d6b5af --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/strtoll/err.BaseTooLarge.d @@ -0,0 +1,35 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright (c) 2012, Joyent, Inc. All rights reserved. + */ + +/* + * ASSERTION: + * The largest base we will accept is Base 36 -- i.e. using all of 0-9 and + * A-Z as numerals. + * + * SECTION: Actions and Subroutines/strtoll() + */ + +#pragma D option quiet + +BEGIN +{ + printf("%d\n", strtoll("0", 37)); + exit(0); +} + +ERROR +{ + exit(1); +} diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/strtoll/err.BaseTooSmall.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/strtoll/err.BaseTooSmall.d new file mode 100644 index 0000000..de56b50 --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/strtoll/err.BaseTooSmall.d @@ -0,0 +1,34 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright (c) 2012, Joyent, Inc. All rights reserved. + */ + +/* + * ASSERTION: + * The smallest base we will accept is Base 2. + * + * SECTION: Actions and Subroutines/strtoll() + */ + +#pragma D option quiet + +BEGIN +{ + printf("%d\n", strtoll("0", 1)); + exit(0); +} + +ERROR +{ + exit(1); +} diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/strtoll/tst.strtoll.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/strtoll/tst.strtoll.d new file mode 100644 index 0000000..0b1812a --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/strtoll/tst.strtoll.d @@ -0,0 +1,66 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright (c) 2012, Joyent, Inc. All rights reserved. + */ + +/* + * ASSERTION: + * Test the strtoll() subroutine. + * + * SECTION: Actions and Subroutines/strtoll() + */ + +#pragma D option quiet + +BEGIN +{ + + /* minimum base (2) and maximum base (36): */ + printf("%d\n", strtoll("0", 2)); + printf("%d\n", strtoll("1", 36)); + + /* simple tests: */ + printf("%d\n", strtoll("0x20", 16)); + printf("%d\n", strtoll("-32", 10)); + printf("%d\n", strtoll("010", 8)); + printf("%d\n", strtoll("101010", 2)); + + /* INT64_MIN and INT64_MAX: */ + printf("%d\n", strtoll("9223372036854775807")); + printf("%d\n", strtoll("-9223372036854775808")); + printf("%d\n", strtoll("0777777777777777777777", 8)); + printf("%d\n", strtoll("-01000000000000000000000", 8)); + + /* wrapping: */ + printf("%d\n", strtoll("1000000000000000000000", 8)); + printf("%d\n", strtoll("-1000000000000000000001", 8)); + + /* hex without prefix: */ + printf("%d\n", strtoll("baddcafe", 16)); + + /* stopping at first out-of-base character: */ + printf("%d\n", strtoll("12j", 10)); + printf("%d\n", strtoll("102", 2)); + + /* base 36: */ + printf("%d\n", strtoll("-0DTrace4EverZ", 36)); + + /* base 10 is assumed: */ + printf("%d\n", strtoll("1985")); + printf("%d\n", strtoll("-2012")); + + /* empty string: */ + printf("%d\n", strtoll("")); + + exit(0); +} diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/strtoll/tst.strtoll.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/strtoll/tst.strtoll.d.out new file mode 100644 index 0000000..d12eb9c --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/strtoll/tst.strtoll.d.out @@ -0,0 +1,20 @@ +0 +1 +32 +-32 +8 +42 +9223372036854775807 +-9223372036854775808 +9223372036854775807 +-9223372036854775808 +-9223372036854775808 +9223372036854775807 +3135097598 +12 +2 +-1819882045752187535 +1985 +-2012 +0 + diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/err.invalidpid.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/err.invalidpid.d new file mode 100644 index 0000000..4865d81 --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/err.invalidpid.d @@ -0,0 +1,21 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright (c) 2013 Joyent, Inc. All rights reserved. + */ + +#pragma D option quiet + +BEGIN +{ + trace((pidfoo`int)0); +} diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/err.invalidpid2.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/err.invalidpid2.d new file mode 100644 index 0000000..bafed12 --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/err.invalidpid2.d @@ -0,0 +1,21 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright (c) 2013 Joyent, Inc. All rights reserved. + */ + +#pragma D option quiet + +BEGIN +{ + trace((pid8foo`int)0); +} diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/err.invalidpid3.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/err.invalidpid3.d new file mode 100644 index 0000000..fb9443a --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/err.invalidpid3.d @@ -0,0 +1,21 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright (c) 2013 Joyent, Inc. All rights reserved. + */ + +#pragma D option quiet + +BEGIN +{ + trace((pid0`int)0); +} diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/err.invalidtype.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/err.invalidtype.ksh new file mode 100644 index 0000000..978cde3 --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/err.invalidtype.ksh @@ -0,0 +1,34 @@ +#! /usr/bin/ksh +# +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright (c) 2013 Joyent, Inc. All rights reserved. +# + +# +# While it's hard to be completely certain that a type of the name we want +# doesn't exist, we're going to try to pick a name which is rather unique. +# + +if [ $# != 1 ]; then + echo expected one argument: '<'dtrace-path'>' + exit 2 +fi + +dtrace=$1 +t="season_8_mountain_of_madness_t" +pid=$$ + +rc=`$dtrace -n "BEGIN{ trace(pid$pid`$t)0); }"` + +exit $rc diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/err.invalidtype2.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/err.invalidtype2.ksh new file mode 100644 index 0000000..e64ed52 --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/err.invalidtype2.ksh @@ -0,0 +1,35 @@ +#! /usr/bin/ksh +# +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright (c) 2013 Joyent, Inc. All rights reserved. +# + +# +# While it's hard to be completely certain that a type of the name we want +# doesn't exist, we're going to try to pick a name which is rather +# unique. This time we're also going to use the pid$target alias. +# + +if [ $# != 1 ]; then + echo expected one argument: '<'dtrace-path'>' + exit 2 +fi + +dtrace=$1 +t="season_8_mountain_of_madness_t" +pid=$$ + +rc=`$dtrace -n "BEGIN{ trace(pid`$t)0); }"` -p $pid + +exit $rc diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/err.user64mode.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/err.user64mode.ksh new file mode 100644 index 0000000..d987c8d --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/err.user64mode.ksh @@ -0,0 +1,90 @@ +#! /usr/bin/ksh +# +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright (c) 2013 Joyent, Inc. All rights reserved. +# + +# +# This test is purposefully using a 64-bit DTrace and thus 64-bit types +# when compared with a 32-bit process. This test uses the userland +# keyword and so the implicit copyin should access illegal memory and +# thus exit. +# + +if [ $# != 1 ]; then + echo expected one argument: '<'dtrace-path'>' + exit 2 +fi + +dtrace=$1 +t="zelda_info_t" +exe="tst.chasestrings.exe" + +elfdump "./$exe" | grep -q '.SUNW_ctf' +if [[ $? -ne 0 ]]; then + echo "CTF does not exist in $exe, that's a bug" >&2 + exit 1 +fi + +./$exe & +pid=$! + +$dtrace -64 -qs /dev/stdin <<EOF +typedef struct info { + char *zi_gamename; + int zi_ndungeons; + char *zi_villain; + int zi_haszelda; +} info_t; + +pid$pid::has_princess:entry +/next == 0/ +{ + this->t = (userland info_t *)arg0; + printf("game: %s, dungeon: %d, villain: %s, zelda: %d\n", + stringof(this->t->zi_gamename), this->t->zi_ndungeons, + stringof(this->t->zi_villain), this->t->zi_haszelda); + next = 1; +} + +pid$pid::has_dungeons:entry +/next == 1/ +{ + this->t = (userland info_t *)arg0; + printf("game: %s, dungeon: %d, villain: %s, zelda: %d\n", + stringof(this->t->zi_gamename), this->t->zi_ndungeons, + stringof(this->t->zi_villain), this->t->zi_haszelda); + next = 2; +} + +pid$pid::has_villain:entry +/next == 2/ +{ + this->t = (userland info_t *)arg0; + printf("game: %s, dungeon: %d, villain: %s, zelda: %d\n", + stringof(this->t->zi_gamename), this->t->zi_ndungeons, + stringof(this->t->zi_villain), this->t->zi_haszelda); + exit(0); +} + +ERROR +{ + exit(1); +} +EOF +rc=$? + +kill -9 $pid + +exit $rc diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.aouttype.c b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.aouttype.c new file mode 100644 index 0000000..a4d25f8 --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.aouttype.c @@ -0,0 +1,46 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2013 (c) Joyent, Inc. All rights reserved. + */ + +/* + * This test tries to make sure that we have CTF data for a type that only this + * binary would reasonably have. In this case, the + * season_7_lisa_the_vegetarian_t. + */ +#include <unistd.h> + +typedef struct season_7_lisa_the_vegetarian { + int fr_salad; +} season_7_lisa_the_vegetarian_t; + +int +sleeper(season_7_lisa_the_vegetarian_t *lp) +{ + for (;;) { + sleep(lp->fr_salad); + } + /*NOTREACHED*/ + return (0); +} + +int +main(void) +{ + season_7_lisa_the_vegetarian_t l; + l.fr_salad = 100; + + sleeper(&l); + + return (0); +} diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.aouttype.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.aouttype.ksh new file mode 100644 index 0000000..151a936 --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.aouttype.ksh @@ -0,0 +1,44 @@ +#! /usr/bin/ksh +# +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright (c) 2013 Joyent, Inc. All rights reserved. +# + +# +# Lookup a type that is inside a.out. +# + +if [ $# != 1 ]; then + echo expected one argument: '<'dtrace-path'>' + exit 2 +fi + +dtrace=$1 +t="season_7_lisa_the_vegetrian_t *" +exe="tst.aouttype.exe" + +elfdump "./$exe" | grep -q '.SUNW_ctf' +if [[ $? -ne 0 ]]; then + echo "CTF does not exist in $exe, that's a bug" >&2 + exit 1 +fi + +./$exe & +pid=$! + +rc=`$dtrace -n "BEGIN{ trace((pid$pid\`$t)0); exit(0); }"` + +kill -9 $pid + +exit $rc diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.chasestrings.c b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.chasestrings.c new file mode 100644 index 0000000..595a7cb --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.chasestrings.c @@ -0,0 +1,79 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2013 (c) Joyent, Inc. All rights reserved. + */ + +/* + * This test takes data from the current binary which is basically running in a + * loop between two functions and our goal is to have two unique types that they + * contain which we can print. + */ + +#include <unistd.h> + +typedef struct zelda_info { + char *zi_gamename; + int zi_ndungeons; + char *zi_villain; + int zi_haszelda; +} zelda_info_t; + +static int +has_princess(zelda_info_t *z) +{ + return (z->zi_haszelda); +} + +static int +has_dungeons(zelda_info_t *z) +{ + return (z->zi_ndungeons != 0); +} + +static const char * +has_villain(zelda_info_t *z) +{ + return (z->zi_villain); +} + +int +main(void) +{ + zelda_info_t oot; + zelda_info_t la; + zelda_info_t lttp; + + oot.zi_gamename = "Ocarina of Time"; + oot.zi_ndungeons = 10; + oot.zi_villain = "Ganondorf"; + oot.zi_haszelda = 1; + + la.zi_gamename = "Link's Awakening"; + la.zi_ndungeons = 9; + la.zi_villain = "Nightmare"; + la.zi_haszelda = 0; + + lttp.zi_gamename = "A Link to the Past"; + lttp.zi_ndungeons = 12; + lttp.zi_villain = "Ganon"; + lttp.zi_haszelda = 1; + + for (;;) { + (void) has_princess(&oot); + (void) has_dungeons(&la); + (void) has_villain(<tp); + sleep(1); + } + + return (0); +} diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.chasestrings.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.chasestrings.ksh new file mode 100644 index 0000000..2502846 --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.chasestrings.ksh @@ -0,0 +1,76 @@ +#! /usr/bin/ksh +# +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright (c) 2013 Joyent, Inc. All rights reserved. +# + +# +# This test is checking that we can read members and that pointers inside +# members point to valid data that is intelligible, eg. strings. +# + +if [ $# != 1 ]; then + echo expected one argument: '<'dtrace-path'>' + exit 2 +fi + +dtrace=$1 +t="zelda_info_t" +exe="tst.chasestrings.exe" + +elfdump "./$exe" | grep -q '.SUNW_ctf' +if [[ $? -ne 0 ]]; then + echo "CTF does not exist in $exe, that's a bug" >&2 + exit 1 +fi + +./$exe & +pid=$! + +$dtrace -qs /dev/stdin <<EOF +pid$pid::has_princess:entry +/next == 0/ +{ + this->t = (pid$pid\`$t *)(copyin(arg0, sizeof (pid$pid\`$t))); + printf("game: %s, dungeon: %d, villain: %s, zelda: %d\n", + copyinstr((uintptr_t)this->t->zi_gamename), this->t->zi_ndungeons, + copyinstr((uintptr_t)this->t->zi_villain), this->t->zi_haszelda); + next = 1; +} + +pid$pid::has_dungeons:entry +/next == 1/ +{ + this->t = (pid$pid\`$t *)(copyin(arg0, sizeof (pid$pid\`$t))); + printf("game: %s, dungeon: %d, villain: %s, zelda: %d\n", + copyinstr((uintptr_t)this->t->zi_gamename), this->t->zi_ndungeons, + copyinstr((uintptr_t)this->t->zi_villain), this->t->zi_haszelda); + next = 2; +} + +pid$pid::has_villain:entry +/next == 2/ +{ + this->t = (pid$pid\`$t *)(copyin(arg0, sizeof (pid$pid\`$t))); + printf("game: %s, dungeon: %d, villain: %s, zelda: %d\n", + copyinstr((uintptr_t)this->t->zi_gamename), this->t->zi_ndungeons, + copyinstr((uintptr_t)this->t->zi_villain), this->t->zi_haszelda); + exit(0); +} +EOF +rc=$? + +kill -9 $pid + +exit $rc diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.chasestrings.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.chasestrings.ksh.out new file mode 100644 index 0000000..219e406 --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.chasestrings.ksh.out @@ -0,0 +1,4 @@ +game: Ocarina of Time, dungeon: 10, villain: Ganondorf, zelda: 1 +game: Link's Awakening, dungeon: 9, villain: Nightmare, zelda: 0 +game: A Link to the Past, dungeon: 12, villain: Ganon, zelda: 1 + diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.libtype.c b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.libtype.c new file mode 100644 index 0000000..916a5b5 --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.libtype.c @@ -0,0 +1,29 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2013 (c) Joyent, Inc. All rights reserved. + */ + +/* + * We're linked against libc which has types, though we do not. + */ +#include <unistd.h> + +int +main(void) +{ + for (;;) { + sleep(1000); + } + /*NOTREACHED*/ + return (0); +} diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.libtype.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.libtype.ksh new file mode 100644 index 0000000..af7c6c8 --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.libtype.ksh @@ -0,0 +1,45 @@ +#! /usr/bin/ksh +# +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright (c) 2013 Joyent, Inc. All rights reserved. +# + +# +# Here we want to make sure that the program in question does not have ctf data +# in its a.out; however, we can get types out of a linked libc. +# + +if [ $# != 1 ]; then + echo expected one argument: '<'dtrace-path'>' + exit 2 +fi + +dtrace=$1 +t="int" +exe="tst.libtype.exe" + +elfdump "./$exe" | grep -q '.SUNW_ctf' +if [[ $? -eq 0 ]]; then + echo "CTF exists in $exe, that's a bug" >&2 + exit 1 +fi + +./$exe & +pid=$! + +rc=`$dtrace -n "BEGIN{ trace((pid$pid\`$t)0); exit(0); }"` + +kill -9 $pid + +exit $rc diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.linkmap.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.linkmap.ksh new file mode 100644 index 0000000..f767def --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.linkmap.ksh @@ -0,0 +1,44 @@ +#! /usr/bin/ksh +# +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright (c) 2013 Joyent, Inc. All rights reserved. +# + +# +# We should be able to see both strstr from libc and from ld on an +# alternate linkmap. +# + +if [ $# != 1 ]; then + echo expected one argument: '<'dtrace-path'>' + exit 2 +fi + +dtrace=$1 + +$dtrace -q -p $$ -s /dev/stdin <<EOF +pid\$target:LM1\`ld.so.1:strstr:entry, +pid\$target:libc.so.1:strstr:entry +{ + exit (0); +} + +BEGIN +{ + exit (0); +} +EOF +rc=$? + +exit $rc diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.pidprint.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.pidprint.ksh new file mode 100644 index 0000000..febb015 --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.pidprint.ksh @@ -0,0 +1,69 @@ +#! /usr/bin/ksh +# +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright (c) 2013 Joyent, Inc. All rights reserved. +# + +# +# Use print() on userland CTF types and verify we get the data we expect. +# + +if [ $# != 1 ]; then + echo expected one argument: '<'dtrace-path'>' + exit 2 +fi + +dtrace=$1 +t="final_fantasy_info_t" +exe="tst.printtype.exe" + +elfdump "./$exe" | grep -q '.SUNW_ctf' +if [[ $? -ne 0 ]]; then + echo "CTF does not exist in $exe, that's a bug" >&2 + exit 1 +fi + +./$exe & +pid=$! + +$dtrace -qs /dev/stdin <<EOF +pid$pid::ff_getgameid:entry +/next == 0/ +{ + print(*args[0]); + printf("\n"); + next = 1; +} + +pid$pid::ff_getpartysize:entry +/next == 1/ +{ + print(*args[0]); + printf("\n"); + next = 2; +} + +pid$pid::ff_getsummons:entry +/next == 2/ +{ + print(*args[0]); + printf("\n"); + exit(0); +} +EOF +rc=$? + +kill -9 $pid + +exit $rc diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.pidprinttarg.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.pidprinttarg.ksh new file mode 100644 index 0000000..7398dc4 --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.pidprinttarg.ksh @@ -0,0 +1,70 @@ +#! /usr/bin/ksh +# +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright (c) 2013 Joyent, Inc. All rights reserved. +# + +# +# Use print() on userland CTF types and verify we get the data we +# expect. This time, use $target to make sure that path works correctly. +# + +if [ $# != 1 ]; then + echo expected one argument: '<'dtrace-path'>' + exit 2 +fi + +dtrace=$1 +t="final_fantasy_info_t" +exe="tst.printtype.exe" + +elfdump "./$exe" | grep -q '.SUNW_ctf' +if [[ $? -ne 0 ]]; then + echo "CTF does not exist in $exe, that's a bug" >&2 + exit 1 +fi + +./$exe & +pid=$! + +$dtrace -p $pid -qs /dev/stdin <<EOF +pid\$target::ff_getgameid:entry +/next == 0/ +{ + print(*args[0]); + printf("\n"); + next = 1; +} + +pid\$target::ff_getpartysize:entry +/next == 1/ +{ + print(*args[0]); + printf("\n"); + next = 2; +} + +pid\$target::ff_getsummons:entry +/next == 2/ +{ + print(*args[0]); + printf("\n"); + exit(0); +} +EOF +rc=$? + +kill -9 $pid + +exit $rc diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.printtype.c b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.printtype.c new file mode 100644 index 0000000..6c27593 --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.printtype.c @@ -0,0 +1,72 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2013 (c) Joyent, Inc. All rights reserved. + */ + +/* + * The point of this is to use print() on various functions to make sure that we + * can print basic structures. Note that we purposefully are making sure that + * there are no pointers here. + */ +#include <unistd.h> + +typedef struct final_fantasy_info { + int ff_gameid; + int ff_partysize; + int ff_hassummons; +} final_fantasy_info_t; + +static int +ff_getgameid(final_fantasy_info_t *f) +{ + return (0); +} + +static int +ff_getpartysize(final_fantasy_info_t *f) +{ + return (0); +} + +static int +ff_getsummons(final_fantasy_info_t *f) +{ + return (0); +} + +int +main(void) +{ + final_fantasy_info_t ffiii, ffx, ffi; + + ffi.ff_gameid = 1; + ffi.ff_partysize = 4; + ffi.ff_hassummons = 0; + + ffiii.ff_gameid = 6; + ffiii.ff_partysize = 4; + ffiii.ff_hassummons = 1; + + ffx.ff_gameid = 10; + ffx.ff_partysize = 3; + ffx.ff_hassummons = 1; + + for (;;) { + ff_getgameid(&ffi); + ff_getpartysize(&ffx); + ff_getsummons(&ffiii); + sleep(1); + } + /*NOTREACHED*/ + return (0); +} diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.printtype.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.printtype.ksh new file mode 100644 index 0000000..dfc1535 --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.printtype.ksh @@ -0,0 +1,69 @@ +#! /usr/bin/ksh +# +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright (c) 2013 Joyent, Inc. All rights reserved. +# + +# +# Use print() on userland CTF types and verify we get the data we expect. +# + +if [ $# != 1 ]; then + echo expected one argument: '<'dtrace-path'>' + exit 2 +fi + +dtrace=$1 +t="final_fantasy_info_t" +exe="tst.printtype.exe" + +elfdump "./$exe" | grep -q '.SUNW_ctf' +if [[ $? -ne 0 ]]; then + echo "CTF does not exist in $exe, that's a bug" >&2 + exit 1 +fi + +./$exe & +pid=$! + +$dtrace -qs /dev/stdin <<EOF +pid$pid::ff_getgameid:entry +/next == 0/ +{ + print(*(pid$pid\`$t *)(copyin(arg0, sizeof (pid$pid\`$t)))); + printf("\n"); + next = 1; +} + +pid$pid::ff_getpartysize:entry +/next == 1/ +{ + print(*(pid$pid\`$t *)(copyin(arg0, sizeof (pid$pid\`$t)))); + printf("\n"); + next = 2; +} + +pid$pid::ff_getsummons:entry +/next == 2/ +{ + print(*(pid$pid\`$t *)(copyin(arg0, sizeof (pid$pid\`$t)))); + printf("\n"); + exit(0); +} +EOF +rc=$? + +kill -9 $pid + +exit $rc diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.printtype.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.printtype.ksh.out new file mode 100644 index 0000000..1770ba2 --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.printtype.ksh.out @@ -0,0 +1,16 @@ +final_fantasy_info_t { + int ff_gameid = 0x1 + int ff_partysize = 0x4 + int ff_hassummons = 0 +} +final_fantasy_info_t { + int ff_gameid = 0xa + int ff_partysize = 0x3 + int ff_hassummons = 0x1 +} +final_fantasy_info_t { + int ff_gameid = 0x6 + int ff_partysize = 0x4 + int ff_hassummons = 0x1 +} + diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.printtypetarg.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.printtypetarg.ksh new file mode 100644 index 0000000..025d4a8 --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.printtypetarg.ksh @@ -0,0 +1,70 @@ +#! /usr/bin/ksh +# +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright (c) 2013 Joyent, Inc. All rights reserved. +# + +# +# Use print() on userland CTF types and verify we get the data we +# expect. Use the pid` alias for $target. +# + +if [ $# != 1 ]; then + echo expected one argument: '<'dtrace-path'>' + exit 2 +fi + +dtrace=$1 +t="final_fantasy_info_t" +exe="tst.printtype.exe" + +elfdump "./$exe" | grep -q '.SUNW_ctf' +if [[ $? -ne 0 ]]; then + echo "CTF does not exist in $exe, that's a bug" >&2 + exit 1 +fi + +./$exe & +pid=$! + +$dtrace -p $pid -qs /dev/stdin <<EOF +pid\$target::ff_getgameid:entry +/next == 0/ +{ + print(*(pid\`$t *)(copyin(arg0, sizeof (pid\`$t)))); + printf("\n"); + next = 1; +} + +pid\$target::ff_getpartysize:entry +/next == 1/ +{ + print(*(pid\`$t *)(copyin(arg0, sizeof (pid\`$t)))); + printf("\n"); + next = 2; +} + +pid\$target::ff_getsummons:entry +/next == 2/ +{ + print(*(pid\`$t *)(copyin(arg0, sizeof (pid\`$t)))); + printf("\n"); + exit(0); +} +EOF +rc=$? + +kill -9 $pid + +exit $rc diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.userlandkey.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.userlandkey.ksh new file mode 100644 index 0000000..58811ff --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.userlandkey.ksh @@ -0,0 +1,83 @@ +#! /usr/bin/ksh +# +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright (c) 2013 Joyent, Inc. All rights reserved. +# + +# +# Simple test that if we manually use the userland keyword that it +# works. +# + +if [ $# != 1 ]; then + echo expected one argument: '<'dtrace-path'>' + exit 2 +fi + +dtrace=$1 +t="zelda_info_t" +exe="tst.chasestrings.exe" + +elfdump "./$exe" | grep -q '.SUNW_ctf' +if [[ $? -ne 0 ]]; then + echo "CTF does not exist in $exe, that's a bug" >&2 + exit 1 +fi + +./$exe & +pid=$! + +$dtrace -32 -qs /dev/stdin <<EOF +typedef struct info { + char *zi_gamename; + int zi_ndungeons; + char *zi_villain; + int zi_haszelda; +} info_t; + +pid$pid::has_princess:entry +/next == 0/ +{ + this->t = (userland info_t *)arg0; + printf("game: %s, dungeon: %d, villain: %s, zelda: %d\n", + stringof(this->t->zi_gamename), this->t->zi_ndungeons, + stringof(this->t->zi_villain), this->t->zi_haszelda); + next = 1; +} + +pid$pid::has_dungeons:entry +/next == 1/ +{ + this->t = (userland info_t *)arg0; + printf("game: %s, dungeon: %d, villain: %s, zelda: %d\n", + stringof(this->t->zi_gamename), this->t->zi_ndungeons, + stringof(this->t->zi_villain), this->t->zi_haszelda); + next = 2; +} + +pid$pid::has_villain:entry +/next == 2/ +{ + this->t = (userland info_t *)arg0; + printf("game: %s, dungeon: %d, villain: %s, zelda: %d\n", + stringof(this->t->zi_gamename), this->t->zi_ndungeons, + stringof(this->t->zi_villain), this->t->zi_haszelda); + exit(0); +} +EOF +rc=$? + +kill -9 $pid + +exit $rc diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.userlandkey.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.userlandkey.ksh.out new file mode 100644 index 0000000..219e406 --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.userlandkey.ksh.out @@ -0,0 +1,4 @@ +game: Ocarina of Time, dungeon: 10, villain: Ganondorf, zelda: 1 +game: Link's Awakening, dungeon: 9, villain: Nightmare, zelda: 0 +game: A Link to the Past, dungeon: 12, villain: Ganon, zelda: 1 + diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.userstrings.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.userstrings.ksh new file mode 100644 index 0000000..79d79de --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.userstrings.ksh @@ -0,0 +1,72 @@ +#! /usr/bin/ksh +# +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright (c) 2013 Joyent, Inc. All rights reserved. +# + +# +# This test is checking that we can read members and that pointers inside +# members point to valid data that is intelligible, eg. strings. +# + +if [ $# != 1 ]; then + echo expected one argument: '<'dtrace-path'>' + exit 2 +fi + +dtrace=$1 +exe="tst.chasestrings.exe" + +elfdump "./$exe" | grep -q '.SUNW_ctf' +if [[ $? -ne 0 ]]; then + echo "CTF does not exist in $exe, that's a bug" >&2 + exit 1 +fi + +./$exe & +pid=$! + +$dtrace -qs /dev/stdin <<EOF +pid$pid::has_princess:entry +/next == 0/ +{ + printf("game: %s, dungeon: %d, villain: %s, zelda: %d\n", + stringof(args[0]->zi_gamename), args[0]->zi_ndungeons, + stringof(args[0]->zi_villain), args[0]->zi_haszelda); + next = 1; +} + +pid$pid::has_dungeons:entry +/next == 1/ +{ + printf("game: %s, dungeon: %d, villain: %s, zelda: %d\n", + stringof(args[0]->zi_gamename), args[0]->zi_ndungeons, + stringof(args[0]->zi_villain), args[0]->zi_haszelda); + next = 2; +} + +pid$pid::has_villain:entry +/next == 2/ +{ + printf("game: %s, dungeon: %d, villain: %s, zelda: %d\n", + stringof(args[0]->zi_gamename), args[0]->zi_ndungeons, + stringof(args[0]->zi_villain), args[0]->zi_haszelda); + exit(0); +} +EOF +rc=$? + +kill -9 $pid + +exit $rc diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.userstrings.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.userstrings.ksh.out new file mode 100644 index 0000000..219e406 --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.userstrings.ksh.out @@ -0,0 +1,4 @@ +game: Ocarina of Time, dungeon: 10, villain: Ganondorf, zelda: 1 +game: Link's Awakening, dungeon: 9, villain: Nightmare, zelda: 0 +game: A Link to the Past, dungeon: 12, villain: Ganon, zelda: 1 + diff --git a/cddl/contrib/opensolaris/common/ctf/ctf_open.c b/cddl/contrib/opensolaris/common/ctf/ctf_open.c index 2148389..001cf5c 100644 --- a/cddl/contrib/opensolaris/common/ctf/ctf_open.c +++ b/cddl/contrib/opensolaris/common/ctf/ctf_open.c @@ -25,7 +25,7 @@ * Use is subject to license terms. */ /* - * Copyright (c) 2012, Joyent, Inc. All rights reserved. + * Copyright (c) 2013, Joyent, Inc. All rights reserved. */ #include <ctf_impl.h> @@ -788,6 +788,92 @@ bad: } /* + * Dupliate a ctf_file_t and its underlying section information into a new + * container. This works by copying the three ctf_sect_t's of the original + * container if they exist and passing those into ctf_bufopen. To copy those, we + * mmap anonymous memory with ctf_data_alloc and bcopy the data across. It's not + * the cheapest thing, but it's what we've got. + */ +ctf_file_t * +ctf_dup(ctf_file_t *ofp) +{ + ctf_file_t *fp; + ctf_sect_t ctfsect, symsect, strsect; + ctf_sect_t *ctp, *symp, *strp; + void *cbuf, *symbuf, *strbuf; + int err; + + cbuf = symbuf = strbuf = NULL; + /* + * The ctfsect isn't allowed to not exist, but the symbol and string + * section might not. We only need to copy the data of the section, not + * the name, as ctf_bufopen will take care of that. + */ + bcopy(&ofp->ctf_data, &ctfsect, sizeof (ctf_sect_t)); + cbuf = ctf_data_alloc(ctfsect.cts_size); + if (cbuf == NULL) { + (void) ctf_set_errno(ofp, ECTF_MMAP); + return (NULL); + } + + bcopy(ctfsect.cts_data, cbuf, ctfsect.cts_size); + ctf_data_protect(cbuf, ctfsect.cts_size); + ctfsect.cts_data = cbuf; + ctfsect.cts_offset = 0; + ctp = &ctfsect; + + if (ofp->ctf_symtab.cts_data != NULL) { + bcopy(&ofp->ctf_symtab, &symsect, sizeof (ctf_sect_t)); + symbuf = ctf_data_alloc(symsect.cts_size); + if (symbuf == NULL) { + (void) ctf_set_errno(ofp, ECTF_MMAP); + goto err; + } + bcopy(symsect.cts_data, symbuf, symsect.cts_size); + ctf_data_protect(symbuf, symsect.cts_size); + symsect.cts_data = symbuf; + symsect.cts_offset = 0; + symp = &symsect; + } else { + symp = NULL; + } + + if (ofp->ctf_strtab.cts_data != NULL) { + bcopy(&ofp->ctf_strtab, &strsect, sizeof (ctf_sect_t)); + strbuf = ctf_data_alloc(strsect.cts_size); + if (strbuf == NULL) { + (void) ctf_set_errno(ofp, ECTF_MMAP); + goto err; + } + bcopy(strsect.cts_data, strbuf, strsect.cts_size); + ctf_data_protect(strbuf, strsect.cts_size); + strsect.cts_data = strbuf; + strsect.cts_offset = 0; + strp = &strsect; + } else { + strp = NULL; + } + + fp = ctf_bufopen(ctp, symp, strp, &err); + if (fp == NULL) { + (void) ctf_set_errno(ofp, err); + goto err; + } + + fp->ctf_flags |= LCTF_MMAP; + + return (fp); + +err: + ctf_data_free(cbuf, ctfsect.cts_size); + if (symbuf != NULL) + ctf_data_free(symbuf, symsect.cts_size); + if (strbuf != NULL) + ctf_data_free(strbuf, strsect.cts_size); + return (NULL); +} + +/* * Close the specified CTF container and free associated data structures. Note * that ctf_close() is a reference counted operation: if the specified file is * the parent of other active containers, its reference count will be greater diff --git a/cddl/contrib/opensolaris/common/ctf/ctf_types.c b/cddl/contrib/opensolaris/common/ctf/ctf_types.c index 290c518..ab1b9ff 100644 --- a/cddl/contrib/opensolaris/common/ctf/ctf_types.c +++ b/cddl/contrib/opensolaris/common/ctf/ctf_types.c @@ -25,8 +25,6 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <ctf_impl.h> ssize_t @@ -199,8 +197,9 @@ ctf_type_resolve(ctf_file_t *fp, ctf_id_t type) * Lookup the given type ID and print a string name for it into buf. Return * the actual number of bytes (not including \0) needed to format the name. */ -ssize_t -ctf_type_lname(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len) +static ssize_t +ctf_type_qlname(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len, + const char *qname) { ctf_decl_t cd; ctf_decl_node_t *cdp; @@ -255,6 +254,8 @@ ctf_type_lname(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len) case CTF_K_INTEGER: case CTF_K_FLOAT: case CTF_K_TYPEDEF: + if (qname != NULL) + ctf_decl_sprintf(&cd, "%s`", qname); ctf_decl_sprintf(&cd, "%s", name); break; case CTF_K_POINTER: @@ -268,13 +269,22 @@ ctf_type_lname(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len) break; case CTF_K_STRUCT: case CTF_K_FORWARD: - ctf_decl_sprintf(&cd, "struct %s", name); + ctf_decl_sprintf(&cd, "struct "); + if (qname != NULL) + ctf_decl_sprintf(&cd, "%s`", qname); + ctf_decl_sprintf(&cd, "%s", name); break; case CTF_K_UNION: - ctf_decl_sprintf(&cd, "union %s", name); + ctf_decl_sprintf(&cd, "union "); + if (qname != NULL) + ctf_decl_sprintf(&cd, "%s`", qname); + ctf_decl_sprintf(&cd, "%s", name); break; case CTF_K_ENUM: - ctf_decl_sprintf(&cd, "enum %s", name); + ctf_decl_sprintf(&cd, "enum "); + if (qname != NULL) + ctf_decl_sprintf(&cd, "%s`", qname); + ctf_decl_sprintf(&cd, "%s", name); break; case CTF_K_VOLATILE: ctf_decl_sprintf(&cd, "volatile"); @@ -301,6 +311,12 @@ ctf_type_lname(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len) return (cd.cd_len); } +ssize_t +ctf_type_lname(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len) +{ + return (ctf_type_qlname(fp, type, buf, len, NULL)); +} + /* * Lookup the given type ID and print a string name for it into buf. If buf * is too small, return NULL: the ECTF_NAMELEN error is set on 'fp' for us. @@ -308,10 +324,19 @@ ctf_type_lname(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len) char * ctf_type_name(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len) { - ssize_t rv = ctf_type_lname(fp, type, buf, len); + ssize_t rv = ctf_type_qlname(fp, type, buf, len, NULL); + return (rv >= 0 && rv < len ? buf : NULL); +} + +char * +ctf_type_qname(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len, + const char *qname) +{ + ssize_t rv = ctf_type_qlname(fp, type, buf, len, qname); return (rv >= 0 && rv < len ? buf : NULL); } + /* * Resolve the type down to a base type node, and then return the size * of the type storage in bytes. diff --git a/cddl/contrib/opensolaris/common/util/strtolctype.h b/cddl/contrib/opensolaris/common/util/strtolctype.h new file mode 100644 index 0000000..a1d1836 --- /dev/null +++ b/cddl/contrib/opensolaris/common/util/strtolctype.h @@ -0,0 +1,79 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +/* Copyright (c) 1988 AT&T */ +/* All Rights Reserved */ + +#ifndef _COMMON_UTIL_CTYPE_H +#define _COMMON_UTIL_CTYPE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * This header file contains a collection of macros that the strtou?ll? + * functions in common/util use to test characters. What we need is a kernel + * version of ctype.h. + * + * NOTE: These macros are used within several DTrace probe context functions. + * They must not be altered to make function calls or perform actions not + * safe in probe context. + */ + +#if defined(sun) && (defined(_KERNEL) || defined(_BOOT)) + +#define isalnum(ch) (isalpha(ch) || isdigit(ch)) +#define isalpha(ch) (isupper(ch) || islower(ch)) +#define isdigit(ch) ((ch) >= '0' && (ch) <= '9') +#define islower(ch) ((ch) >= 'a' && (ch) <= 'z') +#define isspace(ch) (((ch) == ' ') || ((ch) == '\r') || ((ch) == '\n') || \ + ((ch) == '\t') || ((ch) == '\f')) +#define isupper(ch) ((ch) >= 'A' && (ch) <= 'Z') +#define isxdigit(ch) (isdigit(ch) || ((ch) >= 'a' && (ch) <= 'f') || \ + ((ch) >= 'A' && (ch) <= 'F')) + +#endif /* _KERNEL || _BOOT */ + +#define DIGIT(x) \ + (isdigit(x) ? (x) - '0' : islower(x) ? (x) + 10 - 'a' : (x) + 10 - 'A') + +#define MBASE ('z' - 'a' + 1 + 10) + +/* + * The following macro is a version of isalnum() that limits alphabetic + * characters to the ranges a-z and A-Z; locale dependent characters will not + * return 1. The members of a-z and A-Z are assumed to be in ascending order + * and contiguous. + */ +#define lisalnum(x) \ + (isdigit(x) || ((x) >= 'a' && (x) <= 'z') || ((x) >= 'A' && (x) <= 'Z')) + +#ifdef __cplusplus +} +#endif + +#endif /* _COMMON_UTIL_CTYPE_H */ diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_aggregate.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_aggregate.c index b0f2b4a..6b571fa 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_aggregate.c +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_aggregate.c @@ -25,7 +25,7 @@ */ /* - * Copyright (c) 2011, Joyent, Inc. All rights reserved. + * Copyright (c) 2013, Joyent, Inc. All rights reserved. * Copyright (c) 2012 by Delphix. All rights reserved. */ @@ -1301,6 +1301,231 @@ dtrace_aggregate_walk(dtrace_hdl_t *dtp, dtrace_aggregate_f *func, void *arg) } static int +dt_aggregate_total(dtrace_hdl_t *dtp, boolean_t clear) +{ + dt_ahashent_t *h; + dtrace_aggdata_t **total; + dtrace_aggid_t max = DTRACE_AGGVARIDNONE, id; + dt_aggregate_t *agp = &dtp->dt_aggregate; + dt_ahash_t *hash = &agp->dtat_hash; + uint32_t tflags; + + tflags = DTRACE_A_TOTAL | DTRACE_A_HASNEGATIVES | DTRACE_A_HASPOSITIVES; + + /* + * If we need to deliver per-aggregation totals, we're going to take + * three passes over the aggregate: one to clear everything out and + * determine our maximum aggregation ID, one to actually total + * everything up, and a final pass to assign the totals to the + * individual elements. + */ + for (h = hash->dtah_all; h != NULL; h = h->dtahe_nextall) { + dtrace_aggdata_t *aggdata = &h->dtahe_data; + + if ((id = dt_aggregate_aggvarid(h)) > max) + max = id; + + aggdata->dtada_total = 0; + aggdata->dtada_flags &= ~tflags; + } + + if (clear || max == DTRACE_AGGVARIDNONE) + return (0); + + total = dt_zalloc(dtp, (max + 1) * sizeof (dtrace_aggdata_t *)); + + if (total == NULL) + return (-1); + + for (h = hash->dtah_all; h != NULL; h = h->dtahe_nextall) { + dtrace_aggdata_t *aggdata = &h->dtahe_data; + dtrace_aggdesc_t *agg = aggdata->dtada_desc; + dtrace_recdesc_t *rec; + caddr_t data; + int64_t val, *addr; + + rec = &agg->dtagd_rec[agg->dtagd_nrecs - 1]; + data = aggdata->dtada_data; + addr = (int64_t *)(uintptr_t)(data + rec->dtrd_offset); + + switch (rec->dtrd_action) { + case DTRACEAGG_STDDEV: + val = dt_stddev((uint64_t *)addr, 1); + break; + + case DTRACEAGG_SUM: + case DTRACEAGG_COUNT: + val = *addr; + break; + + case DTRACEAGG_AVG: + val = addr[0] ? (addr[1] / addr[0]) : 0; + break; + + default: + continue; + } + + if (total[agg->dtagd_varid] == NULL) { + total[agg->dtagd_varid] = aggdata; + aggdata->dtada_flags |= DTRACE_A_TOTAL; + } else { + aggdata = total[agg->dtagd_varid]; + } + + if (val > 0) + aggdata->dtada_flags |= DTRACE_A_HASPOSITIVES; + + if (val < 0) { + aggdata->dtada_flags |= DTRACE_A_HASNEGATIVES; + val = -val; + } + + if (dtp->dt_options[DTRACEOPT_AGGZOOM] != DTRACEOPT_UNSET) { + val = (int64_t)((long double)val * + (1 / DTRACE_AGGZOOM_MAX)); + + if (val > aggdata->dtada_total) + aggdata->dtada_total = val; + } else { + aggdata->dtada_total += val; + } + } + + /* + * And now one final pass to set everyone's total. + */ + for (h = hash->dtah_all; h != NULL; h = h->dtahe_nextall) { + dtrace_aggdata_t *aggdata = &h->dtahe_data, *t; + dtrace_aggdesc_t *agg = aggdata->dtada_desc; + + if ((t = total[agg->dtagd_varid]) == NULL || aggdata == t) + continue; + + aggdata->dtada_total = t->dtada_total; + aggdata->dtada_flags |= (t->dtada_flags & tflags); + } + + dt_free(dtp, total); + + return (0); +} + +static int +dt_aggregate_minmaxbin(dtrace_hdl_t *dtp, boolean_t clear) +{ + dt_ahashent_t *h; + dtrace_aggdata_t **minmax; + dtrace_aggid_t max = DTRACE_AGGVARIDNONE, id; + dt_aggregate_t *agp = &dtp->dt_aggregate; + dt_ahash_t *hash = &agp->dtat_hash; + + for (h = hash->dtah_all; h != NULL; h = h->dtahe_nextall) { + dtrace_aggdata_t *aggdata = &h->dtahe_data; + + if ((id = dt_aggregate_aggvarid(h)) > max) + max = id; + + aggdata->dtada_minbin = 0; + aggdata->dtada_maxbin = 0; + aggdata->dtada_flags &= ~DTRACE_A_MINMAXBIN; + } + + if (clear || max == DTRACE_AGGVARIDNONE) + return (0); + + minmax = dt_zalloc(dtp, (max + 1) * sizeof (dtrace_aggdata_t *)); + + if (minmax == NULL) + return (-1); + + for (h = hash->dtah_all; h != NULL; h = h->dtahe_nextall) { + dtrace_aggdata_t *aggdata = &h->dtahe_data; + dtrace_aggdesc_t *agg = aggdata->dtada_desc; + dtrace_recdesc_t *rec; + caddr_t data; + int64_t *addr; + int minbin = -1, maxbin = -1, i; + int start = 0, size; + + rec = &agg->dtagd_rec[agg->dtagd_nrecs - 1]; + size = rec->dtrd_size / sizeof (int64_t); + data = aggdata->dtada_data; + addr = (int64_t *)(uintptr_t)(data + rec->dtrd_offset); + + switch (rec->dtrd_action) { + case DTRACEAGG_LQUANTIZE: + /* + * For lquantize(), we always display the entire range + * of the aggregation when aggpack is set. + */ + start = 1; + minbin = start; + maxbin = size - 1 - start; + break; + + case DTRACEAGG_QUANTIZE: + for (i = start; i < size; i++) { + if (!addr[i]) + continue; + + if (minbin == -1) + minbin = i - start; + + maxbin = i - start; + } + + if (minbin == -1) { + /* + * If we have no data (e.g., due to a clear() + * or negative increments), we'll use the + * zero bucket as both our min and max. + */ + minbin = maxbin = DTRACE_QUANTIZE_ZEROBUCKET; + } + + break; + + default: + continue; + } + + if (minmax[agg->dtagd_varid] == NULL) { + minmax[agg->dtagd_varid] = aggdata; + aggdata->dtada_flags |= DTRACE_A_MINMAXBIN; + aggdata->dtada_minbin = minbin; + aggdata->dtada_maxbin = maxbin; + continue; + } + + if (minbin < minmax[agg->dtagd_varid]->dtada_minbin) + minmax[agg->dtagd_varid]->dtada_minbin = minbin; + + if (maxbin > minmax[agg->dtagd_varid]->dtada_maxbin) + minmax[agg->dtagd_varid]->dtada_maxbin = maxbin; + } + + /* + * And now one final pass to set everyone's minbin and maxbin. + */ + for (h = hash->dtah_all; h != NULL; h = h->dtahe_nextall) { + dtrace_aggdata_t *aggdata = &h->dtahe_data, *mm; + dtrace_aggdesc_t *agg = aggdata->dtada_desc; + + if ((mm = minmax[agg->dtagd_varid]) == NULL || aggdata == mm) + continue; + + aggdata->dtada_minbin = mm->dtada_minbin; + aggdata->dtada_maxbin = mm->dtada_maxbin; + aggdata->dtada_flags |= DTRACE_A_MINMAXBIN; + } + + dt_free(dtp, minmax); + + return (0); +} + +static int dt_aggregate_walk_sorted(dtrace_hdl_t *dtp, dtrace_aggregate_f *func, void *arg, int (*sfunc)(const void *, const void *)) @@ -1309,6 +1534,23 @@ dt_aggregate_walk_sorted(dtrace_hdl_t *dtp, dt_ahashent_t *h, **sorted; dt_ahash_t *hash = &agp->dtat_hash; size_t i, nentries = 0; + int rval = -1; + + agp->dtat_flags &= ~(DTRACE_A_TOTAL | DTRACE_A_MINMAXBIN); + + if (dtp->dt_options[DTRACEOPT_AGGHIST] != DTRACEOPT_UNSET) { + agp->dtat_flags |= DTRACE_A_TOTAL; + + if (dt_aggregate_total(dtp, B_FALSE) != 0) + return (-1); + } + + if (dtp->dt_options[DTRACEOPT_AGGPACK] != DTRACEOPT_UNSET) { + agp->dtat_flags |= DTRACE_A_MINMAXBIN; + + if (dt_aggregate_minmaxbin(dtp, B_FALSE) != 0) + return (-1); + } for (h = hash->dtah_all; h != NULL; h = h->dtahe_nextall) nentries++; @@ -1316,7 +1558,7 @@ dt_aggregate_walk_sorted(dtrace_hdl_t *dtp, sorted = dt_alloc(dtp, nentries * sizeof (dt_ahashent_t *)); if (sorted == NULL) - return (-1); + goto out; for (h = hash->dtah_all, i = 0; h != NULL; h = h->dtahe_nextall) sorted[i++] = h; @@ -1340,14 +1582,20 @@ dt_aggregate_walk_sorted(dtrace_hdl_t *dtp, for (i = 0; i < nentries; i++) { h = sorted[i]; - if (dt_aggwalk_rval(dtp, h, func(&h->dtahe_data, arg)) == -1) { - dt_free(dtp, sorted); - return (-1); - } + if (dt_aggwalk_rval(dtp, h, func(&h->dtahe_data, arg)) == -1) + goto out; } + rval = 0; +out: + if (agp->dtat_flags & DTRACE_A_TOTAL) + (void) dt_aggregate_total(dtp, B_TRUE); + + if (agp->dtat_flags & DTRACE_A_MINMAXBIN) + (void) dt_aggregate_minmaxbin(dtp, B_TRUE); + dt_free(dtp, sorted); - return (0); + return (rval); } int @@ -1870,6 +2118,8 @@ dtrace_aggregate_print(dtrace_hdl_t *dtp, FILE *fp, { dt_print_aggdata_t pd; + bzero(&pd, sizeof (pd)); + pd.dtpa_dtp = dtp; pd.dtpa_fp = fp; pd.dtpa_allunprint = 1; diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_as.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_as.c index 457b8fd..f937261 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_as.c +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_as.c @@ -23,8 +23,10 @@ * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ - -#pragma ident "%Z%%M% %I% %E% SMI" +/* + * Copyright (c) 2013 by Delphix. All rights reserved. + * Copyright (c) 2013 Joyent, Inc. All rights reserved. + */ #include <sys/types.h> #include <strings.h> @@ -125,7 +127,7 @@ dt_copyvar(dt_idhash_t *dhp, dt_ident_t *idp, void *data) dvp->dtdv_flags |= DIFV_F_MOD; bzero(&dn, sizeof (dn)); - dt_node_type_assign(&dn, idp->di_ctfp, idp->di_type); + dt_node_type_assign(&dn, idp->di_ctfp, idp->di_type, B_FALSE); dt_node_diftype(pcb->pcb_hdl, &dn, &dvp->dtdv_type); idp->di_flags &= ~(DT_IDFLG_DIFR | DT_IDFLG_DIFW); diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_cc.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_cc.c index 64b98c4..a19152e 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_cc.c +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_cc.c @@ -21,7 +21,7 @@ /* * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2011, Joyent Inc. All rights reserved. + * Copyright (c) 2013, Joyent Inc. All rights reserved. * Copyright (c) 2012 by Delphix. All rights reserved. */ @@ -663,6 +663,8 @@ dt_action_printflike(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp, static void dt_action_trace(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp) { + int ctflib; + dtrace_actdesc_t *ap = dt_stmt_action(dtp, sdp); boolean_t istrace = (dnp->dn_ident->di_id == DT_ACT_TRACE); const char *act = istrace ? "trace" : "print"; @@ -694,7 +696,10 @@ dt_action_trace(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp) * like arrays and function pointers that can't be resolved by * ctf_type_lookup(). This is later processed by dtrace_dof_create() * and turned into a reference into the string table so that we can - * get the type information when we process the data after the fact. + * get the type information when we process the data after the fact. In + * the case where we are referring to userland CTF data, we also need to + * to identify which ctf container in question we care about and encode + * that within the name. */ if (dnp->dn_ident->di_id == DT_ACT_PRINT) { dt_node_t *dret; @@ -705,11 +710,27 @@ dt_action_trace(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp) dmp = dt_module_lookup_by_ctf(dtp, dret->dn_ctfp); n = snprintf(NULL, 0, "%s`%ld", dmp->dm_name, dret->dn_type) + 1; + if (dmp->dm_pid != 0) { + ctflib = dt_module_getlibid(dtp, dmp, dret->dn_ctfp); + assert(ctflib >= 0); + n = snprintf(NULL, 0, "%s`%d`%ld", dmp->dm_name, + ctflib, dret->dn_type) + 1; + } else { + n = snprintf(NULL, 0, "%s`%ld", dmp->dm_name, + dret->dn_type) + 1; + } sdp->dtsd_strdata = dt_alloc(dtp, n); if (sdp->dtsd_strdata == NULL) longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM); (void) snprintf(sdp->dtsd_strdata, n, "%s`%ld", dmp->dm_name, dret->dn_type); + if (dmp->dm_pid != 0) { + (void) snprintf(sdp->dtsd_strdata, n, "%s`%d`%ld", + dmp->dm_name, ctflib, dret->dn_type); + } else { + (void) snprintf(sdp->dtsd_strdata, n, "%s`%ld", + dmp->dm_name, dret->dn_type); + } } ap->dtad_difo = dt_as(yypcb); diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_consume.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_consume.c index 8d9e494..ae1ed00 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_consume.c +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_consume.c @@ -24,7 +24,7 @@ */ /* - * Copyright (c) 2011, Joyent, Inc. All rights reserved. + * Copyright (c) 2013, Joyent, Inc. All rights reserved. * Copyright (c) 2012 by Delphix. All rights reserved. */ @@ -59,6 +59,25 @@ dt_fabsl(long double x) return (x); } +static int +dt_ndigits(long long val) +{ + int rval = 1; + long long cmp = 10; + + if (val < 0) { + val = val == INT64_MIN ? INT64_MAX : -val; + rval++; + } + + while (val > cmp && cmp > 0) { + rval++; + cmp *= 10; + } + + return (rval < 4 ? 4 : rval); +} + /* * 128-bit arithmetic functions needed to support the stddev() aggregating * action. @@ -487,7 +506,125 @@ dt_nullrec() return (DTRACE_CONSUME_NEXT); } -int +static void +dt_quantize_total(dtrace_hdl_t *dtp, int64_t datum, long double *total) +{ + long double val = dt_fabsl((long double)datum); + + if (dtp->dt_options[DTRACEOPT_AGGZOOM] == DTRACEOPT_UNSET) { + *total += val; + return; + } + + /* + * If we're zooming in on an aggregation, we want the height of the + * highest value to be approximately 95% of total bar height -- so we + * adjust up by the reciprocal of DTRACE_AGGZOOM_MAX when comparing to + * our highest value. + */ + val *= 1 / DTRACE_AGGZOOM_MAX; + + if (*total < val) + *total = val; +} + +static int +dt_print_quanthdr(dtrace_hdl_t *dtp, FILE *fp, int width) +{ + return (dt_printf(dtp, fp, "\n%*s %41s %-9s\n", + width ? width : 16, width ? "key" : "value", + "------------- Distribution -------------", "count")); +} + +static int +dt_print_quanthdr_packed(dtrace_hdl_t *dtp, FILE *fp, int width, + const dtrace_aggdata_t *aggdata, dtrace_actkind_t action) +{ + int min = aggdata->dtada_minbin, max = aggdata->dtada_maxbin; + int minwidth, maxwidth, i; + + assert(action == DTRACEAGG_QUANTIZE || action == DTRACEAGG_LQUANTIZE); + + if (action == DTRACEAGG_QUANTIZE) { + if (min != 0 && min != DTRACE_QUANTIZE_ZEROBUCKET) + min--; + + if (max < DTRACE_QUANTIZE_NBUCKETS - 1) + max++; + + minwidth = dt_ndigits(DTRACE_QUANTIZE_BUCKETVAL(min)); + maxwidth = dt_ndigits(DTRACE_QUANTIZE_BUCKETVAL(max)); + } else { + maxwidth = 8; + minwidth = maxwidth - 1; + max++; + } + + if (dt_printf(dtp, fp, "\n%*s %*s .", + width, width > 0 ? "key" : "", minwidth, "min") < 0) + return (-1); + + for (i = min; i <= max; i++) { + if (dt_printf(dtp, fp, "-") < 0) + return (-1); + } + + return (dt_printf(dtp, fp, ". %*s | count\n", -maxwidth, "max")); +} + +/* + * We use a subset of the Unicode Block Elements (U+2588 through U+258F, + * inclusive) to represent aggregations via UTF-8 -- which are expressed via + * 3-byte UTF-8 sequences. + */ +#define DTRACE_AGGUTF8_FULL 0x2588 +#define DTRACE_AGGUTF8_BASE 0x258f +#define DTRACE_AGGUTF8_LEVELS 8 + +#define DTRACE_AGGUTF8_BYTE0(val) (0xe0 | ((val) >> 12)) +#define DTRACE_AGGUTF8_BYTE1(val) (0x80 | (((val) >> 6) & 0x3f)) +#define DTRACE_AGGUTF8_BYTE2(val) (0x80 | ((val) & 0x3f)) + +static int +dt_print_quantline_utf8(dtrace_hdl_t *dtp, FILE *fp, int64_t val, + uint64_t normal, long double total) +{ + uint_t len = 40, i, whole, partial; + long double f = (dt_fabsl((long double)val) * len) / total; + const char *spaces = " "; + + whole = (uint_t)f; + partial = (uint_t)((f - (long double)(uint_t)f) * + (long double)DTRACE_AGGUTF8_LEVELS); + + if (dt_printf(dtp, fp, "|") < 0) + return (-1); + + for (i = 0; i < whole; i++) { + if (dt_printf(dtp, fp, "%c%c%c", + DTRACE_AGGUTF8_BYTE0(DTRACE_AGGUTF8_FULL), + DTRACE_AGGUTF8_BYTE1(DTRACE_AGGUTF8_FULL), + DTRACE_AGGUTF8_BYTE2(DTRACE_AGGUTF8_FULL)) < 0) + return (-1); + } + + if (partial != 0) { + partial = DTRACE_AGGUTF8_BASE - (partial - 1); + + if (dt_printf(dtp, fp, "%c%c%c", + DTRACE_AGGUTF8_BYTE0(partial), + DTRACE_AGGUTF8_BYTE1(partial), + DTRACE_AGGUTF8_BYTE2(partial)) < 0) + return (-1); + + i++; + } + + return (dt_printf(dtp, fp, "%s %-9lld\n", spaces + i, + (long long)val / normal)); +} + +static int dt_print_quantline(dtrace_hdl_t *dtp, FILE *fp, int64_t val, uint64_t normal, long double total, char positives, char negatives) { @@ -505,6 +642,11 @@ dt_print_quantline(dtrace_hdl_t *dtp, FILE *fp, int64_t val, if (!negatives) { if (positives) { + if (dtp->dt_encoding == DT_ENCODING_UTF8) { + return (dt_print_quantline_utf8(dtp, fp, val, + normal, total)); + } + f = (dt_fabsl((long double)val) * len) / total; depth = (uint_t)(f + 0.5); } else { @@ -547,6 +689,73 @@ dt_print_quantline(dtrace_hdl_t *dtp, FILE *fp, int64_t val, } } +/* + * As with UTF-8 printing of aggregations, we use a subset of the Unicode + * Block Elements (U+2581 through U+2588, inclusive) to represent our packed + * aggregation. + */ +#define DTRACE_AGGPACK_BASE 0x2581 +#define DTRACE_AGGPACK_LEVELS 8 + +static int +dt_print_packed(dtrace_hdl_t *dtp, FILE *fp, + long double datum, long double total) +{ + static boolean_t utf8_checked = B_FALSE; + static boolean_t utf8; + char *ascii = "__xxxxXX"; + char *neg = "vvvvVV"; + unsigned int len; + long double val; + + if (!utf8_checked) { + char *term; + + /* + * We want to determine if we can reasonably emit UTF-8 for our + * packed aggregation. To do this, we will check for terminals + * that are known to be primitive to emit UTF-8 on these. + */ + utf8_checked = B_TRUE; + + if (dtp->dt_encoding == DT_ENCODING_ASCII) { + utf8 = B_FALSE; + } else if (dtp->dt_encoding == DT_ENCODING_UTF8) { + utf8 = B_TRUE; + } else if ((term = getenv("TERM")) != NULL && + (strcmp(term, "sun") == 0 || + strcmp(term, "sun-color") == 0) || + strcmp(term, "dumb") == 0) { + utf8 = B_FALSE; + } else { + utf8 = B_TRUE; + } + } + + if (datum == 0) + return (dt_printf(dtp, fp, " ")); + + if (datum < 0) { + len = strlen(neg); + val = dt_fabsl(datum * (len - 1)) / total; + return (dt_printf(dtp, fp, "%c", neg[(uint_t)(val + 0.5)])); + } + + if (utf8) { + int block = DTRACE_AGGPACK_BASE + (unsigned int)(((datum * + (DTRACE_AGGPACK_LEVELS - 1)) / total) + 0.5); + + return (dt_printf(dtp, fp, "%c%c%c", + DTRACE_AGGUTF8_BYTE0(block), + DTRACE_AGGUTF8_BYTE1(block), + DTRACE_AGGUTF8_BYTE2(block))); + } + + len = strlen(ascii); + val = (datum * (len - 1)) / total; + return (dt_printf(dtp, fp, "%c", ascii[(uint_t)(val + 0.5)])); +} + int dt_print_quantize(dtrace_hdl_t *dtp, FILE *fp, const void *addr, size_t size, uint64_t normal) @@ -564,9 +773,9 @@ dt_print_quantize(dtrace_hdl_t *dtp, FILE *fp, const void *addr, if (first_bin == DTRACE_QUANTIZE_NBUCKETS - 1) { /* - * There isn't any data. This is possible if (and only if) - * negative increment values have been used. In this case, - * we'll print the buckets around 0. + * There isn't any data. This is possible if the aggregation + * has been clear()'d or if negative increment values have been + * used. Regardless, we'll print the buckets around 0. */ first_bin = DTRACE_QUANTIZE_ZEROBUCKET - 1; last_bin = DTRACE_QUANTIZE_ZEROBUCKET + 1; @@ -584,11 +793,10 @@ dt_print_quantize(dtrace_hdl_t *dtp, FILE *fp, const void *addr, for (i = first_bin; i <= last_bin; i++) { positives |= (data[i] > 0); negatives |= (data[i] < 0); - total += dt_fabsl((long double)data[i]); + dt_quantize_total(dtp, data[i], &total); } - if (dt_printf(dtp, fp, "\n%16s %41s %-9s\n", "value", - "------------- Distribution -------------", "count") < 0) + if (dt_print_quanthdr(dtp, fp, 0) < 0) return (-1); for (i = first_bin; i <= last_bin; i++) { @@ -605,6 +813,48 @@ dt_print_quantize(dtrace_hdl_t *dtp, FILE *fp, const void *addr, } int +dt_print_quantize_packed(dtrace_hdl_t *dtp, FILE *fp, const void *addr, + size_t size, const dtrace_aggdata_t *aggdata) +{ + const int64_t *data = addr; + long double total = 0, count = 0; + int min = aggdata->dtada_minbin, max = aggdata->dtada_maxbin, i; + int64_t minval, maxval; + + if (size != DTRACE_QUANTIZE_NBUCKETS * sizeof (uint64_t)) + return (dt_set_errno(dtp, EDT_DMISMATCH)); + + if (min != 0 && min != DTRACE_QUANTIZE_ZEROBUCKET) + min--; + + if (max < DTRACE_QUANTIZE_NBUCKETS - 1) + max++; + + minval = DTRACE_QUANTIZE_BUCKETVAL(min); + maxval = DTRACE_QUANTIZE_BUCKETVAL(max); + + if (dt_printf(dtp, fp, " %*lld :", dt_ndigits(minval), + (long long)minval) < 0) + return (-1); + + for (i = min; i <= max; i++) { + dt_quantize_total(dtp, data[i], &total); + count += data[i]; + } + + for (i = min; i <= max; i++) { + if (dt_print_packed(dtp, fp, data[i], total) < 0) + return (-1); + } + + if (dt_printf(dtp, fp, ": %*lld | %lld\n", + -dt_ndigits(maxval), (long long)maxval, (long long)count) < 0) + return (-1); + + return (0); +} + +int dt_print_lquantize(dtrace_hdl_t *dtp, FILE *fp, const void *addr, size_t size, uint64_t normal) { @@ -651,7 +901,7 @@ dt_print_lquantize(dtrace_hdl_t *dtp, FILE *fp, const void *addr, for (i = first_bin; i <= last_bin; i++) { positives |= (data[i] > 0); negatives |= (data[i] < 0); - total += dt_fabsl((long double)data[i]); + dt_quantize_total(dtp, data[i], &total); } if (dt_printf(dtp, fp, "\n%16s %41s %-9s\n", "value", @@ -663,8 +913,7 @@ dt_print_lquantize(dtrace_hdl_t *dtp, FILE *fp, const void *addr, int err; if (i == 0) { - (void) snprintf(c, sizeof (c), "< %d", - base / (uint32_t)normal); + (void) snprintf(c, sizeof (c), "< %d", base); err = dt_printf(dtp, fp, "%16s ", c); } else if (i == levels + 1) { (void) snprintf(c, sizeof (c), ">= %d", @@ -683,6 +932,59 @@ dt_print_lquantize(dtrace_hdl_t *dtp, FILE *fp, const void *addr, return (0); } +/*ARGSUSED*/ +int +dt_print_lquantize_packed(dtrace_hdl_t *dtp, FILE *fp, const void *addr, + size_t size, const dtrace_aggdata_t *aggdata) +{ + const int64_t *data = addr; + long double total = 0, count = 0; + int min, max, base, err; + uint64_t arg; + uint16_t step, levels; + char c[32]; + unsigned int i; + + if (size < sizeof (uint64_t)) + return (dt_set_errno(dtp, EDT_DMISMATCH)); + + arg = *data++; + size -= sizeof (uint64_t); + + base = DTRACE_LQUANTIZE_BASE(arg); + step = DTRACE_LQUANTIZE_STEP(arg); + levels = DTRACE_LQUANTIZE_LEVELS(arg); + + if (size != sizeof (uint64_t) * (levels + 2)) + return (dt_set_errno(dtp, EDT_DMISMATCH)); + + min = 0; + max = levels + 1; + + if (min == 0) { + (void) snprintf(c, sizeof (c), "< %d", base); + err = dt_printf(dtp, fp, "%8s :", c); + } else { + err = dt_printf(dtp, fp, "%8d :", base + (min - 1) * step); + } + + if (err < 0) + return (-1); + + for (i = min; i <= max; i++) { + dt_quantize_total(dtp, data[i], &total); + count += data[i]; + } + + for (i = min; i <= max; i++) { + if (dt_print_packed(dtp, fp, data[i], total) < 0) + return (-1); + } + + (void) snprintf(c, sizeof (c), ">= %d", base + (levels * step)); + return (dt_printf(dtp, fp, ": %-8s | %lld\n", c, (long long)count)); +} + int dt_print_llquantize(dtrace_hdl_t *dtp, FILE *fp, const void *addr, size_t size, uint64_t normal) @@ -740,7 +1042,7 @@ dt_print_llquantize(dtrace_hdl_t *dtp, FILE *fp, const void *addr, for (i = first_bin; i <= last_bin; i++) { positives |= (data[i] > 0); negatives |= (data[i] < 0); - total += dt_fabsl((long double)data[i]); + dt_quantize_total(dtp, data[i], &total); } if (dt_printf(dtp, fp, "\n%16s %41s %-9s\n", "value", @@ -823,7 +1125,7 @@ dt_print_stddev(dtrace_hdl_t *dtp, FILE *fp, caddr_t addr, } /*ARGSUSED*/ -int +static int dt_print_bytes(dtrace_hdl_t *dtp, FILE *fp, caddr_t addr, size_t nbytes, int width, int quiet, int forceraw) { @@ -876,10 +1178,12 @@ dt_print_bytes(dtrace_hdl_t *dtp, FILE *fp, caddr_t addr, if (j != nbytes) break; - if (quiet) + if (quiet) { return (dt_printf(dtp, fp, "%s", c)); - else - return (dt_printf(dtp, fp, " %-*s", width, c)); + } else { + return (dt_printf(dtp, fp, " %s%*s", + width < 0 ? " " : "", width, c)); + } } break; @@ -1793,10 +2097,83 @@ dt_trunc(dtrace_hdl_t *dtp, caddr_t base, dtrace_recdesc_t *rec) static int dt_print_datum(dtrace_hdl_t *dtp, FILE *fp, dtrace_recdesc_t *rec, - caddr_t addr, size_t size, uint64_t normal) + caddr_t addr, size_t size, const dtrace_aggdata_t *aggdata, + uint64_t normal, dt_print_aggdata_t *pd) { - int err; + int err, width; dtrace_actkind_t act = rec->dtrd_action; + boolean_t packed = pd->dtpa_agghist || pd->dtpa_aggpack; + dtrace_aggdesc_t *agg = aggdata->dtada_desc; + + static struct { + size_t size; + int width; + int packedwidth; + } *fmt, fmttab[] = { + { sizeof (uint8_t), 3, 3 }, + { sizeof (uint16_t), 5, 5 }, + { sizeof (uint32_t), 8, 8 }, + { sizeof (uint64_t), 16, 16 }, + { 0, -50, 16 } + }; + + if (packed && pd->dtpa_agghisthdr != agg->dtagd_varid) { + dtrace_recdesc_t *r; + + width = 0; + + /* + * To print our quantization header for either an agghist or + * aggpack aggregation, we need to iterate through all of our + * of our records to determine their width. + */ + for (r = rec; !DTRACEACT_ISAGG(r->dtrd_action); r++) { + for (fmt = fmttab; fmt->size && + fmt->size != r->dtrd_size; fmt++) + continue; + + width += fmt->packedwidth + 1; + } + + if (pd->dtpa_agghist) { + if (dt_print_quanthdr(dtp, fp, width) < 0) + return (-1); + } else { + if (dt_print_quanthdr_packed(dtp, fp, + width, aggdata, r->dtrd_action) < 0) + return (-1); + } + + pd->dtpa_agghisthdr = agg->dtagd_varid; + } + + if (pd->dtpa_agghist && DTRACEACT_ISAGG(act)) { + char positives = aggdata->dtada_flags & DTRACE_A_HASPOSITIVES; + char negatives = aggdata->dtada_flags & DTRACE_A_HASNEGATIVES; + int64_t val; + + assert(act == DTRACEAGG_SUM || act == DTRACEAGG_COUNT); + val = (long long)*((uint64_t *)addr); + + if (dt_printf(dtp, fp, " ") < 0) + return (-1); + + return (dt_print_quantline(dtp, fp, val, normal, + aggdata->dtada_total, positives, negatives)); + } + + if (pd->dtpa_aggpack && DTRACEACT_ISAGG(act)) { + switch (act) { + case DTRACEAGG_QUANTIZE: + return (dt_print_quantize_packed(dtp, + fp, addr, size, aggdata)); + case DTRACEAGG_LQUANTIZE: + return (dt_print_lquantize_packed(dtp, + fp, addr, size, aggdata)); + default: + break; + } + } switch (act) { case DTRACEACT_STACK: @@ -1839,28 +2216,33 @@ dt_print_datum(dtrace_hdl_t *dtp, FILE *fp, dtrace_recdesc_t *rec, break; } + for (fmt = fmttab; fmt->size && fmt->size != size; fmt++) + continue; + + width = packed ? fmt->packedwidth : fmt->width; + switch (size) { case sizeof (uint64_t): - err = dt_printf(dtp, fp, " %16lld", + err = dt_printf(dtp, fp, " %*lld", width, /* LINTED - alignment */ (long long)*((uint64_t *)addr) / normal); break; case sizeof (uint32_t): /* LINTED - alignment */ - err = dt_printf(dtp, fp, " %8d", *((uint32_t *)addr) / + err = dt_printf(dtp, fp, " %*d", width, *((uint32_t *)addr) / (uint32_t)normal); break; case sizeof (uint16_t): /* LINTED - alignment */ - err = dt_printf(dtp, fp, " %5d", *((uint16_t *)addr) / + err = dt_printf(dtp, fp, " %*d", width, *((uint16_t *)addr) / (uint32_t)normal); break; case sizeof (uint8_t): - err = dt_printf(dtp, fp, " %3d", *((uint8_t *)addr) / + err = dt_printf(dtp, fp, " %*d", width, *((uint8_t *)addr) / (uint32_t)normal); break; default: - err = dt_print_bytes(dtp, fp, addr, size, 50, 0, 0); + err = dt_print_bytes(dtp, fp, addr, size, width, 0, 0); break; } @@ -1881,6 +2263,9 @@ dt_print_aggs(const dtrace_aggdata_t **aggsdata, int naggvars, void *arg) caddr_t addr; size_t size; + pd->dtpa_agghist = (aggdata->dtada_flags & DTRACE_A_TOTAL); + pd->dtpa_aggpack = (aggdata->dtada_flags & DTRACE_A_MINMAXBIN); + /* * Iterate over each record description in the key, printing the traced * data, skipping the first datum (the tuple member created by the @@ -1897,7 +2282,8 @@ dt_print_aggs(const dtrace_aggdata_t **aggsdata, int naggvars, void *arg) break; } - if (dt_print_datum(dtp, fp, rec, addr, size, 1) < 0) + if (dt_print_datum(dtp, fp, rec, addr, + size, aggdata, 1, pd) < 0) return (-1); if (dt_buffered_flush(dtp, NULL, rec, aggdata, @@ -1920,7 +2306,8 @@ dt_print_aggs(const dtrace_aggdata_t **aggsdata, int naggvars, void *arg) assert(DTRACEACT_ISAGG(act)); normal = aggdata->dtada_normal; - if (dt_print_datum(dtp, fp, rec, addr, size, normal) < 0) + if (dt_print_datum(dtp, fp, rec, addr, + size, aggdata, normal, pd) < 0) return (-1); if (dt_buffered_flush(dtp, NULL, rec, aggdata, @@ -1931,8 +2318,10 @@ dt_print_aggs(const dtrace_aggdata_t **aggsdata, int naggvars, void *arg) agg->dtagd_flags |= DTRACE_AGD_PRINTED; } - if (dt_printf(dtp, fp, "\n") < 0) - return (-1); + if (!pd->dtpa_agghist && !pd->dtpa_aggpack) { + if (dt_printf(dtp, fp, "\n") < 0) + return (-1); + } if (dt_buffered_flush(dtp, NULL, NULL, aggdata, DTRACE_BUFDATA_AGGFORMAT | DTRACE_BUFDATA_AGGLAST) < 0) @@ -2401,7 +2790,7 @@ nofmt: } n = dt_print_bytes(dtp, fp, addr, - tracememsize, 33, quiet, 1); + tracememsize, -33, quiet, 1); tracememsize = 0; @@ -2434,7 +2823,7 @@ nofmt: break; default: n = dt_print_bytes(dtp, fp, addr, - rec->dtrd_size, 33, quiet, 0); + rec->dtrd_size, -33, quiet, 0); break; } diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_decl.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_decl.c index 871fdd5..d717d56 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_decl.c +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_decl.c @@ -21,7 +21,8 @@ */ /* * Copyright 2005 Sun Microsystems, Inc. All rights reserved. - * Copyright (c) 2012 by Delphix. All rights reserved. + * Copyright (c) 2013 by Delphix. All rights reserved. + * Copyright (c) 2013 Joyent, Inc. All rights reserved. * Use is subject to license terms. */ @@ -779,7 +780,7 @@ dt_decl_enumerator(char *s, dt_node_t *dnp) yyintdecimal = 0; dnp = dt_node_int(value); - dt_node_type_assign(dnp, dsp->ds_ctfp, dsp->ds_type); + dt_node_type_assign(dnp, dsp->ds_ctfp, dsp->ds_type, B_FALSE); if ((inp = malloc(sizeof (dt_idnode_t))) == NULL) longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM); @@ -821,6 +822,8 @@ dt_decl_type(dt_decl_t *ddp, dtrace_typeinfo_t *tip) char *name; int rv; + tip->dtt_flags = 0; + /* * Based on our current #include depth and decl stack depth, determine * which dynamic CTF module and scope to use when adding any new types. @@ -828,6 +831,9 @@ dt_decl_type(dt_decl_t *ddp, dtrace_typeinfo_t *tip) dmp = yypcb->pcb_idepth ? dtp->dt_cdefs : dtp->dt_ddefs; flag = yypcb->pcb_dstack.ds_next ? CTF_ADD_NONROOT : CTF_ADD_ROOT; + if (ddp->dd_attr & DT_DA_USER) + tip->dtt_flags = DTT_FL_USER; + /* * If we have already cached a CTF type for this decl, then we just * return the type information for the cached type. diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_decl.h b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_decl.h index 2933155..d322875 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_decl.h +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_decl.h @@ -23,12 +23,14 @@ * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ +/* + * Copyright (c) 2013 by Delphix. All rights reserved. + * Copyright (c) 2013 Joyent, Inc. All rights reserved. + */ #ifndef _DT_DECL_H #define _DT_DECL_H -#pragma ident "%Z%%M% %I% %E% SMI" - #include <sys/types.h> #include <libctf.h> #include <dtrace.h> @@ -59,6 +61,7 @@ typedef struct dt_decl { #define DT_DA_RESTRICT 0x0040 /* qualify type as restrict */ #define DT_DA_VOLATILE 0x0080 /* qualify type as volatile */ #define DT_DA_PAREN 0x0100 /* parenthesis tag */ +#define DT_DA_USER 0x0200 /* user-land type specifier */ typedef enum dt_dclass { DT_DC_DEFAULT, /* no storage class specified */ diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_dis.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_dis.c index fff4235..c0af364 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_dis.c +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_dis.c @@ -26,7 +26,8 @@ */ /* - * Copyright (c) 2012 by Delphix. All rights reserved. + * Copyright (c) 2013 by Delphix. All rights reserved. + * Copyright (c) 2013 Joyent, Inc. All rights reserved. */ #include <strings.h> @@ -312,9 +313,10 @@ dt_dis_typestr(const dtrace_diftype_t *t, char *buf, size_t len) (void) snprintf(ckind, sizeof (ckind), "0x%x", t->dtdt_ckind); } - if (t->dtdt_flags & DIF_TF_BYREF) { - (void) snprintf(buf, len, "%s (%s) by ref (size %lu)", - kind, ckind, (ulong_t)t->dtdt_size); + if (t->dtdt_flags & (DIF_TF_BYREF | DIF_TF_BYUREF)) { + (void) snprintf(buf, len, "%s (%s) by %sref (size %lu)", + kind, ckind, (t->dtdt_flags & DIF_TF_BYUREF) ? "user " : "", + (ulong_t)t->dtdt_size); } else { (void) snprintf(buf, len, "%s (%s) (size %lu)", kind, ckind, (ulong_t)t->dtdt_size); diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_error.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_error.c index d8dbbabb..2327ff7 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_error.c +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_error.c @@ -111,7 +111,8 @@ static const struct { { EDT_BADAGGVAR, "Invalid aggregation variable identifier" }, { EDT_OVERSION, "Client requested deprecated version of library" }, { EDT_ENABLING_ERR, "Failed to enable probe" }, - { EDT_NOPROBES, "No probe sites found for declared provider" } + { EDT_NOPROBES, "No probe sites found for declared provider" }, + { EDT_CANTLOAD, "Failed to load module" }, }; static const int _dt_nerr = sizeof (_dt_errlist) / sizeof (_dt_errlist[0]); diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_grammar.y b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_grammar.y index 0c12623..07790f4 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_grammar.y +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_grammar.y @@ -23,8 +23,10 @@ * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ - -#pragma ident "%Z%%M% %I% %E% SMI" +/* + * Copyright (c) 2013 by Delphix. All rights reserved. + * Copyright (c) 2013, Joyent, Inc. All rights reserved. + */ #include <dt_impl.h> @@ -102,6 +104,7 @@ %token DT_KEY_TYPEDEF %token DT_KEY_UNION %token DT_KEY_UNSIGNED +%token DT_KEY_USERLAND %token DT_KEY_VOID %token DT_KEY_VOLATILE %token DT_KEY_WHILE @@ -633,6 +636,7 @@ type_specifier: DT_KEY_VOID { $$ = dt_decl_spec(CTF_K_INTEGER, DUP("void")); } | DT_KEY_DOUBLE { $$ = dt_decl_spec(CTF_K_FLOAT, DUP("double")); } | DT_KEY_SIGNED { $$ = dt_decl_attr(DT_DA_SIGNED); } | DT_KEY_UNSIGNED { $$ = dt_decl_attr(DT_DA_UNSIGNED); } + | DT_KEY_USERLAND { $$ = dt_decl_attr(DT_DA_USER); } | DT_KEY_STRING { $$ = dt_decl_spec(CTF_K_TYPEDEF, DUP("string")); } diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_ident.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_ident.c index 13adbb4..5a2f0e4 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_ident.c +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_ident.c @@ -22,6 +22,8 @@ /* * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright (c) 2013 by Delphix. All rights reserved. + * Copyright (c) 2013 Joyent, Inc. All rights reserved. */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -104,7 +106,7 @@ dt_idcook_sign(dt_node_t *dnp, dt_ident_t *idp, } } - dt_node_type_assign(dnp, idp->di_ctfp, idp->di_type); + dt_node_type_assign(dnp, idp->di_ctfp, idp->di_type, B_FALSE); } /* @@ -163,7 +165,7 @@ dt_idcook_assc(dt_node_t *dnp, dt_ident_t *idp, int argc, dt_node_t *args) if (argc != 0) isp->dis_args[argc - 1].dn_list = NULL; - dt_node_type_assign(dnp, idp->di_ctfp, idp->di_type); + dt_node_type_assign(dnp, idp->di_ctfp, idp->di_type, B_FALSE); } else { dt_idcook_sign(dnp, idp, argc, args, @@ -304,7 +306,7 @@ dt_idcook_func(dt_node_t *dnp, dt_ident_t *idp, int argc, dt_node_t *args) } dt_node_type_assign(&isp->dis_args[i], - dtt.dtt_ctfp, dtt.dtt_type); + dtt.dtt_ctfp, dtt.dtt_type, B_FALSE); } } @@ -391,7 +393,9 @@ dt_idcook_args(dt_node_t *dnp, dt_ident_t *idp, int argc, dt_node_t *ap) dt_node_type_assign(dnp, prp->pr_argv[ap->dn_value].dtt_ctfp, - prp->pr_argv[ap->dn_value].dtt_type); + prp->pr_argv[ap->dn_value].dtt_type, + prp->pr_argv[ap->dn_value].dtt_flags & DTT_FL_USER ? + B_TRUE : B_FALSE); } else if ((dxp = dt_xlator_lookup(dtp, nnp, xnp, DT_XLATE_FUZZY)) != NULL || ( @@ -419,7 +423,8 @@ dt_idcook_args(dt_node_t *dnp, dt_ident_t *idp, int argc, dt_node_t *ap) dnp->dn_ident->di_ctfp = xidp->di_ctfp; dnp->dn_ident->di_type = xidp->di_type; - dt_node_type_assign(dnp, DT_DYN_CTFP(dtp), DT_DYN_TYPE(dtp)); + dt_node_type_assign(dnp, DT_DYN_CTFP(dtp), DT_DYN_TYPE(dtp), + B_FALSE); } else { xyerror(D_ARGS_XLATOR, "translator for %s[%lld] from %s to %s " @@ -465,7 +470,7 @@ dt_idcook_regs(dt_node_t *dnp, dt_ident_t *idp, int argc, dt_node_t *ap) idp->di_ctfp = dtt.dtt_ctfp; idp->di_type = dtt.dtt_type; - dt_node_type_assign(dnp, idp->di_ctfp, idp->di_type); + dt_node_type_assign(dnp, idp->di_ctfp, idp->di_type, B_FALSE); } /*ARGSUSED*/ @@ -487,7 +492,7 @@ dt_idcook_type(dt_node_t *dnp, dt_ident_t *idp, int argc, dt_node_t *args) idp->di_type = dtt.dtt_type; } - dt_node_type_assign(dnp, idp->di_ctfp, idp->di_type); + dt_node_type_assign(dnp, idp->di_ctfp, idp->di_type, B_FALSE); } /*ARGSUSED*/ @@ -495,7 +500,7 @@ static void dt_idcook_thaw(dt_node_t *dnp, dt_ident_t *idp, int argc, dt_node_t *args) { if (idp->di_ctfp != NULL && idp->di_type != CTF_ERR) - dt_node_type_assign(dnp, idp->di_ctfp, idp->di_type); + dt_node_type_assign(dnp, idp->di_ctfp, idp->di_type, B_FALSE); } static void diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_impl.h b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_impl.h index 2bae220..b7abbc2 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_impl.h +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_impl.h @@ -146,6 +146,10 @@ typedef struct dt_module { caddr_t dm_reloc_offset; /* Symbol relocation offset. */ uintptr_t *dm_sec_offsets; #endif + pid_t dm_pid; /* pid for this module */ + uint_t dm_nctflibs; /* number of ctf children libraries */ + ctf_file_t **dm_libctfp; /* process library ctf pointers */ + char **dm_libctfn; /* names of process ctf containers */ } dt_module_t; #define DT_DM_LOADED 0x1 /* module symbol and type data is loaded */ @@ -189,6 +193,9 @@ typedef struct dt_print_aggdata { dtrace_aggvarid_t dtpa_id; /* aggregation variable of interest */ FILE *dtpa_fp; /* file pointer */ int dtpa_allunprint; /* print only unprinted aggregations */ + int dtpa_agghist; /* print aggregation as histogram */ + int dtpa_agghisthdr; /* aggregation histogram hdr printed */ + int dtpa_aggpack; /* pack quantized aggregations */ } dt_print_aggdata_t; typedef struct dt_dirpath { @@ -283,6 +290,7 @@ struct dtrace_hdl { uint_t dt_linktype; /* dtrace link output file type (see below) */ uint_t dt_xlatemode; /* dtrace translator linking mode (see below) */ uint_t dt_stdcmode; /* dtrace stdc compatibility mode (see below) */ + uint_t dt_encoding; /* dtrace output encoding (see below) */ uint_t dt_treedump; /* dtrace tree debug bitmap (see below) */ uint64_t dt_options[DTRACEOPT_MAX]; /* dtrace run-time options */ int dt_version; /* library version requested by client */ @@ -374,6 +382,14 @@ struct dtrace_hdl { #define DT_STDC_XT 3 /* ISO C + K&R C compat with ISO: __STDC__=0 */ /* + * Values for the dt_encoding property, which is used to force a particular + * character encoding (overriding default behavior and/or automatic detection). + */ +#define DT_ENCODING_UNSET 0 +#define DT_ENCODING_ASCII 1 +#define DT_ENCODING_UTF8 2 + +/* * Macro to test whether a given pass bit is set in the dt_treedump bit-vector. * If the bit for pass 'p' is set, the D compiler displays the parse tree for * the program by printing it to stderr at the end of compiler pass 'p'. @@ -536,7 +552,8 @@ enum { EDT_BADAGGVAR, /* invalid aggregation variable identifier */ EDT_OVERSION, /* client is requesting deprecated version */ EDT_ENABLING_ERR, /* failed to enable probe */ - EDT_NOPROBES /* no probes sites for declared provider */ + EDT_NOPROBES, /* no probes sites for declared provider */ + EDT_CANTLOAD /* failed to load a module */ }; /* diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_lex.l b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_lex.l index b31933e..032d303 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_lex.l +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_lex.l @@ -23,6 +23,10 @@ /* * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. */ +/* + * Copyright (c) 2013 by Delphix. All rights reserved. + * Copyright (c) 2013, Joyent, Inc. All rights reserved. + */ #include <string.h> #include <stdlib.h> @@ -93,13 +97,17 @@ static void unput(int); %} %e 1500 /* maximum nodes */ -%p 3700 /* maximum positions */ +%p 4900 /* maximum positions */ %n 600 /* maximum states */ +%a 3000 /* maximum transitions */ %s S0 S1 S2 S3 S4 RGX_AGG "@"[a-zA-Z_][0-9a-zA-Z_]* RGX_PSPEC [-$:a-zA-Z_.?*\\\[\]!][-$:0-9a-zA-Z_.`?*\\\[\]!]* +RGX_ALTIDENT [a-zA-Z_][0-9a-zA-Z_]* +RGX_LMID LM[0-9a-fA-F]+` +RGX_MOD_IDENT [a-zA-Z_`][0-9a-z.A-Z_`]*` RGX_IDENT [a-zA-Z_`][0-9a-zA-Z_`]* RGX_INT ([0-9]+|0[xX][0-9A-Fa-f]+)[uU]?[lL]?[lL]? RGX_FP ([0-9]+("."?)[0-9]*|"."[0-9]+)((e|E)("+"|-)?[0-9]+)?[fFlL]? @@ -169,6 +177,7 @@ if (yypcb->pcb_token != 0) { <S0>typedef return (DT_KEY_TYPEDEF); <S0>union return (DT_KEY_UNION); <S0>unsigned return (DT_KEY_UNSIGNED); +<S0>userland return (DT_KEY_USERLAND); <S0>void return (DT_KEY_VOID); <S0>volatile return (DT_KEY_VOLATILE); <S0>while return (DT_KEY_WHILE); @@ -347,7 +356,9 @@ if (yypcb->pcb_token != 0) { return (DT_TOK_INT); } -<S0>{RGX_IDENT} { +<S0>{RGX_IDENT} | +<S0>{RGX_MOD_IDENT}{RGX_IDENT} | +<S0>{RGX_MOD_IDENT} { return (id_or_type(yytext)); } diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_module.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_module.c index 497faa9..e3905c1 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_module.c +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_module.c @@ -22,6 +22,9 @@ /* * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. */ +/* + * Copyright (c) 2013, Joyent, Inc. All rights reserved. + */ #include <sys/types.h> #if defined(sun) @@ -50,6 +53,7 @@ #include <dirent.h> #if !defined(sun) #include <fcntl.h> +#include <libproc_compat.h> #endif #include <dt_strtab.h> @@ -462,6 +466,9 @@ static const dt_modops_t dt_modops_64 = { dt_module_t * dt_module_create(dtrace_hdl_t *dtp, const char *name) { + long pid; + char *eptr; + dt_ident_t *idp; uint_t h = dt_strtab_hash(name, NULL) % dtp->dt_modbuckets; dt_module_t *dmp; @@ -485,6 +492,32 @@ dt_module_create(dtrace_hdl_t *dtp, const char *name) else dmp->dm_ops = &dt_modops_32; + /* + * Modules for userland processes are special. They always refer to a + * specific process and have a copy of their CTF data from a specific + * instant in time. Any dt_module_t that begins with 'pid' is a module + * for a specific process, much like how any probe description that + * begins with 'pid' is special. pid123 refers to process 123. A module + * that is just 'pid' refers specifically to pid$target. This is + * generally done as D does not currently allow for macros to be + * evaluated when working with types. + */ + if (strncmp(dmp->dm_name, "pid", 3) == 0) { + errno = 0; + if (dmp->dm_name[3] == '\0') { + idp = dt_idhash_lookup(dtp->dt_macros, "target"); + if (idp != NULL && idp->di_id != 0) + dmp->dm_pid = idp->di_id; + } else { + pid = strtol(dmp->dm_name + 3, &eptr, 10); + if (errno == 0 && *eptr == '\0') + dmp->dm_pid = (pid_t)pid; + else + dt_dprintf("encountered malformed pid " + "module: %s\n", dmp->dm_name); + } + } + return (dmp); } @@ -554,12 +587,169 @@ dt_module_load_sect(dtrace_hdl_t *dtp, dt_module_t *dmp, ctf_sect_t *ctsp) return (0); } +typedef struct dt_module_cb_arg { + struct ps_prochandle *dpa_proc; + dtrace_hdl_t *dpa_dtp; + dt_module_t *dpa_dmp; + uint_t dpa_count; +} dt_module_cb_arg_t; + +/* ARGSUSED */ +static int +dt_module_load_proc_count(void *arg, const prmap_t *prmap, const char *obj) +{ + ctf_file_t *fp; + dt_module_cb_arg_t *dcp = arg; + + /* Try to grab a ctf container if it exists */ + fp = Pname_to_ctf(dcp->dpa_proc, obj); + if (fp != NULL) + dcp->dpa_count++; + return (0); +} + +/* ARGSUSED */ +static int +dt_module_load_proc_build(void *arg, const prmap_t *prmap, const char *obj) +{ + ctf_file_t *fp; + char buf[MAXPATHLEN], *p; + dt_module_cb_arg_t *dcp = arg; + int count = dcp->dpa_count; + Lmid_t lmid; + + fp = Pname_to_ctf(dcp->dpa_proc, obj); + if (fp == NULL) + return (0); + fp = ctf_dup(fp); + if (fp == NULL) + return (0); + dcp->dpa_dmp->dm_libctfp[count] = fp; + /* + * While it'd be nice to simply use objname here, because of our prior + * actions we'll always get a resolved object name to its on disk file. + * Like the pid provider, we need to tell a bit of a lie here. The type + * that the user thinks of is in terms of the libraries they requested, + * eg. libc.so.1, they don't care about the fact that it's + * libc_hwcap.so.1. + */ + (void) Pobjname(dcp->dpa_proc, prmap->pr_vaddr, buf, sizeof (buf)); + if ((p = strrchr(buf, '/')) == NULL) + p = buf; + else + p++; + + /* + * If for some reason we can't find a link map id for this module, which + * would be really quite weird. We instead just say the link map id is + * zero. + */ + if (Plmid(dcp->dpa_proc, prmap->pr_vaddr, &lmid) != 0) + lmid = 0; + + if (lmid == 0) + dcp->dpa_dmp->dm_libctfn[count] = strdup(p); + else + (void) asprintf(&dcp->dpa_dmp->dm_libctfn[count], + "LM%x`%s", lmid, p); + if (dcp->dpa_dmp->dm_libctfn[count] == NULL) + return (1); + ctf_setspecific(fp, dcp->dpa_dmp); + dcp->dpa_count++; + return (0); +} + +/* + * We've been asked to load data that belongs to another process. As such we're + * going to pgrab it at this instant, load everything that we might ever care + * about, and then drive on. The reason for this is that the process that we're + * interested in might be changing. As long as we have grabbed it, then this + * can't be a problem for us. + * + * For now, we're actually going to punt on most things and just try to get CTF + * data, nothing else. Basically this is only useful as a source of type + * information, we can't go and do the stacktrace lookups, etc. + */ +static int +dt_module_load_proc(dtrace_hdl_t *dtp, dt_module_t *dmp) +{ + struct ps_prochandle *p; + dt_module_cb_arg_t arg; + + /* + * Note that on success we do not release this hold. We must hold this + * for our life time. + */ + p = dt_proc_grab(dtp, dmp->dm_pid, 0, PGRAB_RDONLY | PGRAB_FORCE); + if (p == NULL) { + dt_dprintf("failed to grab pid: %d\n", (int)dmp->dm_pid); + return (dt_set_errno(dtp, EDT_CANTLOAD)); + } + dt_proc_lock(dtp, p); + + arg.dpa_proc = p; + arg.dpa_dtp = dtp; + arg.dpa_dmp = dmp; + arg.dpa_count = 0; + if (Pobject_iter_resolved(p, dt_module_load_proc_count, &arg) != 0) { + dt_dprintf("failed to iterate objects\n"); + dt_proc_release(dtp, p); + return (dt_set_errno(dtp, EDT_CANTLOAD)); + } + + if (arg.dpa_count == 0) { + dt_dprintf("no ctf data present\n"); + dt_proc_unlock(dtp, p); + dt_proc_release(dtp, p); + return (dt_set_errno(dtp, EDT_CANTLOAD)); + } + + dmp->dm_libctfp = malloc(sizeof (ctf_file_t *) * arg.dpa_count); + if (dmp->dm_libctfp == NULL) { + dt_proc_unlock(dtp, p); + dt_proc_release(dtp, p); + return (dt_set_errno(dtp, EDT_NOMEM)); + } + bzero(dmp->dm_libctfp, sizeof (ctf_file_t *) * arg.dpa_count); + + dmp->dm_libctfn = malloc(sizeof (char *) * arg.dpa_count); + if (dmp->dm_libctfn == NULL) { + free(dmp->dm_libctfp); + dt_proc_unlock(dtp, p); + dt_proc_release(dtp, p); + return (dt_set_errno(dtp, EDT_NOMEM)); + } + bzero(dmp->dm_libctfn, sizeof (char *) * arg.dpa_count); + + dmp->dm_nctflibs = arg.dpa_count; + + arg.dpa_count = 0; + if (Pobject_iter_resolved(p, dt_module_load_proc_build, &arg) != 0) { + dt_proc_unlock(dtp, p); + dt_module_unload(dtp, dmp); + dt_proc_release(dtp, p); + return (dt_set_errno(dtp, EDT_CANTLOAD)); + } + assert(arg.dpa_count == dmp->dm_nctflibs); + dt_dprintf("loaded %d ctf modules for pid %d\n", arg.dpa_count, + (int)dmp->dm_pid); + + dt_proc_unlock(dtp, p); + dt_proc_release(dtp, p); + dmp->dm_flags |= DT_DM_LOADED; + + return (0); +} + int dt_module_load(dtrace_hdl_t *dtp, dt_module_t *dmp) { if (dmp->dm_flags & DT_DM_LOADED) return (0); /* module is already loaded */ + if (dmp->dm_pid != 0) + return (dt_module_load_proc(dtp, dmp)); + dmp->dm_ctdata.cts_name = ".SUNW_ctf"; dmp->dm_ctdata.cts_type = SHT_PROGBITS; dmp->dm_ctdata.cts_flags = 0; @@ -645,6 +835,14 @@ dt_module_load(dtrace_hdl_t *dtp, dt_module_t *dmp) return (0); } +int +dt_module_hasctf(dtrace_hdl_t *dtp, dt_module_t *dmp) +{ + if (dmp->dm_pid != 0 && dmp->dm_nctflibs > 0) + return (1); + return (dt_module_getctf(dtp, dmp) != NULL); +} + ctf_file_t * dt_module_getctf(dtrace_hdl_t *dtp, dt_module_t *dmp) { @@ -718,6 +916,8 @@ err: void dt_module_unload(dtrace_hdl_t *dtp, dt_module_t *dmp) { + int i; + ctf_close(dmp->dm_ctfp); dmp->dm_ctfp = NULL; @@ -733,6 +933,17 @@ dt_module_unload(dtrace_hdl_t *dtp, dt_module_t *dmp) } #endif + if (dmp->dm_libctfp != NULL) { + for (i = 0; i < dmp->dm_nctflibs; i++) { + ctf_close(dmp->dm_libctfp[i]); + free(dmp->dm_libctfn[i]); + } + free(dmp->dm_libctfp); + free(dmp->dm_libctfn); + dmp->dm_libctfp = NULL; + dmp->dm_nctflibs = 0; + } + bzero(&dmp->dm_ctdata, sizeof (ctf_sect_t)); bzero(&dmp->dm_symtab, sizeof (ctf_sect_t)); bzero(&dmp->dm_strtab, sizeof (ctf_sect_t)); @@ -778,6 +989,8 @@ dt_module_unload(dtrace_hdl_t *dtp, dt_module_t *dmp) (void) elf_end(dmp->dm_elf); dmp->dm_elf = NULL; + dmp->dm_pid = 0; + dmp->dm_flags &= ~DT_DM_LOADED; } @@ -866,6 +1079,34 @@ dt_module_modelname(dt_module_t *dmp) return ("32-bit"); } +/* ARGSUSED */ +int +dt_module_getlibid(dtrace_hdl_t *dtp, dt_module_t *dmp, const ctf_file_t *fp) +{ + int i; + + for (i = 0; i < dmp->dm_nctflibs; i++) { + if (dmp->dm_libctfp[i] == fp) + return (i); + } + + return (-1); +} + +/* ARGSUSED */ +ctf_file_t * +dt_module_getctflib(dtrace_hdl_t *dtp, dt_module_t *dmp, const char *name) +{ + int i; + + for (i = 0; i < dmp->dm_nctflibs; i++) { + if (strcmp(dmp->dm_libctfn[i], name) == 0) + return (dmp->dm_libctfp[i]); + } + + return (NULL); +} + /* * Update our module cache by adding an entry for the specified module 'name'. * We create the dt_module_t and populate it using /system/object/<name>/. @@ -1294,8 +1535,10 @@ dtrace_lookup_by_type(dtrace_hdl_t *dtp, const char *object, const char *name, dt_module_t *dmp; int found = 0; ctf_id_t id; - uint_t n; + uint_t n, i; int justone; + ctf_file_t *fp; + char *buf, *p, *q; uint_t mask = 0; /* mask of dt_module flags to match */ uint_t bits = 0; /* flag bits that must be present */ @@ -1310,7 +1553,6 @@ dtrace_lookup_by_type(dtrace_hdl_t *dtp, const char *object, const char *name, return (-1); /* dt_errno is set for us */ n = 1; justone = 1; - } else { if (object == DTRACE_OBJ_KMODS) mask = bits = DT_DM_KERNEL; @@ -1334,7 +1576,7 @@ dtrace_lookup_by_type(dtrace_hdl_t *dtp, const char *object, const char *name, * module. If our search was scoped to only one module then * return immediately leaving dt_errno unmodified. */ - if (dt_module_getctf(dtp, dmp) == NULL) { + if (dt_module_hasctf(dtp, dmp) == 0) { if (justone) return (-1); continue; @@ -1346,13 +1588,38 @@ dtrace_lookup_by_type(dtrace_hdl_t *dtp, const char *object, const char *name, * 'tip' and keep going in the hope that we will locate the * underlying structure definition. Otherwise just return. */ - if ((id = ctf_lookup_by_name(dmp->dm_ctfp, name)) != CTF_ERR) { + if (dmp->dm_pid == 0) { + id = ctf_lookup_by_name(dmp->dm_ctfp, name); + fp = dmp->dm_ctfp; + } else { + if ((p = strchr(name, '`')) != NULL) { + buf = strdup(name); + if (buf == NULL) + return (dt_set_errno(dtp, EDT_NOMEM)); + p = strchr(buf, '`'); + if ((q = strchr(p + 1, '`')) != NULL) + p = q; + *p = '\0'; + fp = dt_module_getctflib(dtp, dmp, buf); + if (fp == NULL || (id = ctf_lookup_by_name(fp, + p + 1)) == CTF_ERR) + id = CTF_ERR; + free(buf); + } else { + for (i = 0; i < dmp->dm_nctflibs; i++) { + fp = dmp->dm_libctfp[i]; + id = ctf_lookup_by_name(fp, name); + if (id != CTF_ERR) + break; + } + } + } + if (id != CTF_ERR) { tip->dtt_object = dmp->dm_name; - tip->dtt_ctfp = dmp->dm_ctfp; + tip->dtt_ctfp = fp; tip->dtt_type = id; - - if (ctf_type_kind(dmp->dm_ctfp, ctf_type_resolve( - dmp->dm_ctfp, id)) != CTF_K_FORWARD) + if (ctf_type_kind(fp, ctf_type_resolve(fp, id)) != + CTF_K_FORWARD) return (0); found++; @@ -1374,6 +1641,7 @@ dtrace_symbol_type(dtrace_hdl_t *dtp, const GElf_Sym *symp, tip->dtt_object = NULL; tip->dtt_ctfp = NULL; tip->dtt_type = CTF_ERR; + tip->dtt_flags = 0; if ((dmp = dt_module_lookup_by_name(dtp, sip->dts_object)) == NULL) return (dt_set_errno(dtp, EDT_NOMOD)); diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_module.h b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_module.h index 8334a2b..d103e02 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_module.h +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_module.h @@ -23,12 +23,13 @@ * Copyright 2004 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ +/* + * Copyright (c) 2013, Joyent, Inc. All rights reserved. + */ #ifndef _DT_MODULE_H #define _DT_MODULE_H -#pragma ident "%Z%%M% %I% %E% SMI" - #include <dt_impl.h> #ifdef __cplusplus @@ -43,11 +44,16 @@ extern void dt_module_destroy(dtrace_hdl_t *, dt_module_t *); extern dt_module_t *dt_module_lookup_by_name(dtrace_hdl_t *, const char *); extern dt_module_t *dt_module_lookup_by_ctf(dtrace_hdl_t *, ctf_file_t *); +extern int dt_module_hasctf(dtrace_hdl_t *, dt_module_t *); extern ctf_file_t *dt_module_getctf(dtrace_hdl_t *, dt_module_t *); extern dt_ident_t *dt_module_extern(dtrace_hdl_t *, dt_module_t *, const char *, const dtrace_typeinfo_t *); extern const char *dt_module_modelname(dt_module_t *); +extern int dt_module_getlibid(dtrace_hdl_t *, dt_module_t *, + const ctf_file_t *); +extern ctf_file_t *dt_module_getctflib(dtrace_hdl_t *, dt_module_t *, + const char *); #ifdef __cplusplus } diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c index 9c9b2a6..cf6f2e9 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c @@ -21,7 +21,7 @@ /* * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2011, Joyent, Inc. All rights reserved. + * Copyright (c) 2013, Joyent, Inc. All rights reserved. * Copyright (c) 2012 by Delphix. All rights reserved. */ @@ -122,8 +122,12 @@ #define DT_VERS_1_8_1 DT_VERSION_NUMBER(1, 8, 1) #define DT_VERS_1_9 DT_VERSION_NUMBER(1, 9, 0) #define DT_VERS_1_9_1 DT_VERSION_NUMBER(1, 9, 1) -#define DT_VERS_LATEST DT_VERS_1_9_1 -#define DT_VERS_STRING "Sun D 1.9.1" +#define DT_VERS_1_10 DT_VERSION_NUMBER(1, 10, 0) +#define DT_VERS_1_11 DT_VERSION_NUMBER(1, 11, 0) +#define DT_VERS_1_12 DT_VERSION_NUMBER(1, 12, 0) +#define DT_VERS_1_12_1 DT_VERSION_NUMBER(1, 12, 1) +#define DT_VERS_LATEST DT_VERS_1_12_1 +#define DT_VERS_STRING "Sun D 1.12.1" const dt_version_t _dtrace_versions[] = { DT_VERS_1_0, /* D API 1.0.0 (PSARC 2001/466) Solaris 10 FCS */ @@ -145,6 +149,10 @@ const dt_version_t _dtrace_versions[] = { DT_VERS_1_8_1, /* D API 1.8.1 */ DT_VERS_1_9, /* D API 1.9 */ DT_VERS_1_9_1, /* D API 1.9.1 */ + DT_VERS_1_10, /* D API 1.10 */ + DT_VERS_1_11, /* D API 1.11 */ + DT_VERS_1_12, /* D API 1.12 */ + DT_VERS_1_12_1, /* D API 1.12.1 */ 0 }; @@ -275,6 +283,8 @@ static const dt_ident_t _dtrace_globals[] = { &dt_idops_func, "uint64_t(uint64_t)" }, { "htons", DT_IDENT_FUNC, 0, DIF_SUBR_HTONS, DT_ATTR_EVOLCMN, DT_VERS_1_3, &dt_idops_func, "uint16_t(uint16_t)" }, +{ "getf", DT_IDENT_FUNC, 0, DIF_SUBR_GETF, DT_ATTR_STABCMN, DT_VERS_1_10, + &dt_idops_func, "file_t *(int)" }, { "gid", DT_IDENT_SCALAR, 0, DIF_VAR_GID, DT_ATTR_STABCMN, DT_VERS_1_0, &dt_idops_type, "gid_t" }, { "id", DT_IDENT_SCALAR, 0, DIF_VAR_ID, DT_ATTR_STABCMN, DT_VERS_1_0, @@ -297,6 +307,8 @@ static const dt_ident_t _dtrace_globals[] = { DT_VERS_1_5, &dt_idops_func, "string(int, void *)" }, { "ipl", DT_IDENT_SCALAR, 0, DIF_VAR_IPL, DT_ATTR_STABCMN, DT_VERS_1_0, &dt_idops_type, "uint_t" }, +{ "json", DT_IDENT_FUNC, 0, DIF_SUBR_JSON, DT_ATTR_STABCMN, DT_VERS_1_11, + &dt_idops_func, "string(const char *, const char *)" }, { "jstack", DT_IDENT_ACTFUNC, 0, DT_ACT_JSTACK, DT_ATTR_STABCMN, DT_VERS_1_0, &dt_idops_func, "stack(...)" }, { "lltostr", DT_IDENT_FUNC, 0, DIF_SUBR_LLTOSTR, DT_ATTR_STABCMN, DT_VERS_1_0, @@ -444,6 +456,8 @@ static const dt_ident_t _dtrace_globals[] = { &dt_idops_func, "string(const char *, const char *)" }, { "strtok", DT_IDENT_FUNC, 0, DIF_SUBR_STRTOK, DT_ATTR_STABCMN, DT_VERS_1_1, &dt_idops_func, "string(const char *, const char *)" }, +{ "strtoll", DT_IDENT_FUNC, 0, DIF_SUBR_STRTOLL, DT_ATTR_STABCMN, DT_VERS_1_11, + &dt_idops_func, "int64_t(const char *, [int])" }, { "substr", DT_IDENT_FUNC, 0, DIF_SUBR_SUBSTR, DT_ATTR_STABCMN, DT_VERS_1_1, &dt_idops_func, "string(const char *, int, [int])" }, { "sum", DT_IDENT_AGGFUNC, 0, DTRACEAGG_SUM, DT_ATTR_STABCMN, DT_VERS_1_0, @@ -1148,6 +1162,7 @@ alloc: dtp->dt_linktype = DT_LTYP_ELF; dtp->dt_xlatemode = DT_XL_STATIC; dtp->dt_stdcmode = DT_STDC_XA; + dtp->dt_encoding = DT_ENCODING_UNSET; dtp->dt_version = version; dtp->dt_fd = dtfd; dtp->dt_ftfd = ftfd; diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_options.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_options.c index c20d250..832af88 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_options.c +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_options.c @@ -25,6 +25,7 @@ */ /* + * Copyright (c) 2013, Joyent, Inc. All rights reserved. * Copyright (c) 2012 by Delphix. All rights reserved. */ @@ -338,6 +339,23 @@ dt_opt_linktype(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) /*ARGSUSED*/ static int +dt_opt_encoding(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) +{ + if (arg == NULL) + return (dt_set_errno(dtp, EDT_BADOPTVAL)); + + if (strcmp(arg, "ascii") == 0) + dtp->dt_encoding = DT_ENCODING_ASCII; + else if (strcmp(arg, "utf8") == 0) + dtp->dt_encoding = DT_ENCODING_UTF8; + else + return (dt_set_errno(dtp, EDT_BADOPTVAL)); + + return (0); +} + +/*ARGSUSED*/ +static int dt_opt_evaltime(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) { if (arg == NULL) @@ -928,6 +946,7 @@ static const dt_option_t _dtrace_ctoptions[] = { { "define", dt_opt_cpp_opts, (uintptr_t)"-D" }, { "droptags", dt_opt_droptags }, { "empty", dt_opt_cflags, DTRACE_C_EMPTY }, + { "encoding", dt_opt_encoding }, { "errtags", dt_opt_cflags, DTRACE_C_ETAGS }, { "evaltime", dt_opt_evaltime }, { "incdir", dt_opt_cpp_opts, (uintptr_t)"-I" }, @@ -988,11 +1007,14 @@ static const dt_option_t _dtrace_rtoptions[] = { * Dynamic run-time options. */ static const dt_option_t _dtrace_drtoptions[] = { + { "agghist", dt_opt_runtime, DTRACEOPT_AGGHIST }, + { "aggpack", dt_opt_runtime, DTRACEOPT_AGGPACK }, { "aggrate", dt_opt_rate, DTRACEOPT_AGGRATE }, { "aggsortkey", dt_opt_runtime, DTRACEOPT_AGGSORTKEY }, { "aggsortkeypos", dt_opt_runtime, DTRACEOPT_AGGSORTKEYPOS }, { "aggsortpos", dt_opt_runtime, DTRACEOPT_AGGSORTPOS }, { "aggsortrev", dt_opt_runtime, DTRACEOPT_AGGSORTREV }, + { "aggzoom", dt_opt_runtime, DTRACEOPT_AGGZOOM }, { "flowindent", dt_opt_runtime, DTRACEOPT_FLOWINDENT }, { "quiet", dt_opt_runtime, DTRACEOPT_QUIET }, { "rawbytes", dt_opt_runtime, DTRACEOPT_RAWBYTES }, diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_parser.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_parser.c index 5b3be7d..6ce3dad 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_parser.c +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_parser.c @@ -22,8 +22,8 @@ /* * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Copyright (c) 2011, Joyent Inc. All rights reserved. - * Copyright (c) 2012 by Delphix. All rights reserved. + * Copyright (c) 2013, Joyent Inc. All rights reserved. + * Copyright (c) 2013 by Delphix. All rights reserved. */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -197,7 +197,7 @@ dt_type_lookup(const char *s, dtrace_typeinfo_t *tip) { static const char delimiters[] = " \t\n\r\v\f*`"; dtrace_hdl_t *dtp = yypcb->pcb_hdl; - const char *p, *q, *end, *obj; + const char *p, *q, *r, *end, *obj; for (p = s, end = s + strlen(s); *p != '\0'; p = q) { while (isspace(*p)) @@ -225,8 +225,23 @@ dt_type_lookup(const char *s, dtrace_typeinfo_t *tip) bcopy(s, type, (size_t)(p - s)); bcopy(q + 1, type + (size_t)(p - s), strlen(q + 1) + 1); - if (strchr(q + 1, '`') != NULL) - return (dt_set_errno(dtp, EDT_BADSCOPE)); + /* + * There may be at most three delimeters. The second + * delimeter is usually used to distinguish the type + * within a given module, however, there could be a link + * map id on the scene in which case that delimeter + * would be the third. We determine presence of the lmid + * if it rouglhly meets the from LM[0-9] + */ + if ((r = strchr(q + 1, '`')) != NULL && + ((r = strchr(r + 1, '`')) != NULL)) { + if (strchr(r + 1, '`') != NULL) + return (dt_set_errno(dtp, + EDT_BADSCOPE)); + if (q[1] != 'L' || q[2] != 'M') + return (dt_set_errno(dtp, + EDT_BADSCOPE)); + } return (dtrace_lookup_by_type(dtp, object, type, tip)); } @@ -256,6 +271,7 @@ dt_type_pointer(dtrace_typeinfo_t *tip) ctf_file_t *ctfp = tip->dtt_ctfp; ctf_id_t type = tip->dtt_type; ctf_id_t base = ctf_type_resolve(ctfp, type); + uint_t bflags = tip->dtt_flags; dt_module_t *dmp; ctf_id_t ptr; @@ -287,6 +303,7 @@ dt_type_pointer(dtrace_typeinfo_t *tip) tip->dtt_object = dmp->dm_name; tip->dtt_ctfp = dmp->dm_ctfp; tip->dtt_type = ptr; + tip->dtt_flags = bflags; return (0); } @@ -390,7 +407,7 @@ void dt_node_promote(dt_node_t *lp, dt_node_t *rp, dt_node_t *dnp) { dt_type_promote(lp, rp, &dnp->dn_ctfp, &dnp->dn_type); - dt_node_type_assign(dnp, dnp->dn_ctfp, dnp->dn_type); + dt_node_type_assign(dnp, dnp->dn_ctfp, dnp->dn_type, B_FALSE); dt_node_attr_assign(dnp, dt_attr_min(lp->dn_attr, rp->dn_attr)); } @@ -659,7 +676,8 @@ dt_node_attr_assign(dt_node_t *dnp, dtrace_attribute_t attr) } void -dt_node_type_assign(dt_node_t *dnp, ctf_file_t *fp, ctf_id_t type) +dt_node_type_assign(dt_node_t *dnp, ctf_file_t *fp, ctf_id_t type, + boolean_t user) { ctf_id_t base = ctf_type_resolve(fp, type); uint_t kind = ctf_type_kind(fp, base); @@ -691,6 +709,9 @@ dt_node_type_assign(dt_node_t *dnp, ctf_file_t *fp, ctf_id_t type) type == DT_DYN_TYPE(yypcb->pcb_hdl)) dnp->dn_flags |= DT_NF_REF; + if (user) + dnp->dn_flags |= DT_NF_USERLAND; + dnp->dn_flags |= DT_NF_COOKED; dnp->dn_ctfp = fp; dnp->dn_type = type; @@ -728,6 +749,7 @@ size_t dt_node_type_size(const dt_node_t *dnp) { ctf_id_t base; + dtrace_hdl_t *dtp = yypcb->pcb_hdl; if (dnp->dn_kind == DT_NODE_STRING) return (strlen(dnp->dn_string) + 1); @@ -740,6 +762,20 @@ dt_node_type_size(const dt_node_t *dnp) if (ctf_type_kind(dnp->dn_ctfp, base) == CTF_K_FORWARD) return (0); + /* + * Here we have a 32-bit user pointer that is being used with a 64-bit + * kernel. When we're using it and its tagged as a userland reference -- + * then we need to keep it as a 32-bit pointer. However, if we are + * referring to it as a kernel address, eg. being used after a copyin() + * then we need to make sure that we actually return the kernel's size + * of a pointer, 8 bytes. + */ + if (ctf_type_kind(dnp->dn_ctfp, base) == CTF_K_POINTER && + ctf_getmodel(dnp->dn_ctfp) == CTF_MODEL_ILP32 && + !(dnp->dn_flags & DT_NF_USERLAND) && + dtp->dt_conf.dtc_ctfmodel == CTF_MODEL_LP64) + return (8); + return (ctf_type_size(dnp->dn_ctfp, dnp->dn_type)); } @@ -1226,7 +1262,7 @@ dt_node_int(uintmax_t value) if (value <= dtp->dt_ints[i].did_limit) { dt_node_type_assign(dnp, dtp->dt_ints[i].did_ctfp, - dtp->dt_ints[i].did_type); + dtp->dt_ints[i].did_type, B_FALSE); /* * If a prefix character is present in macro text, add @@ -1261,7 +1297,7 @@ dt_node_string(char *string) dnp = dt_node_alloc(DT_NODE_STRING); dnp->dn_op = DT_TOK_STRING; dnp->dn_string = string; - dt_node_type_assign(dnp, DT_STR_CTFP(dtp), DT_STR_TYPE(dtp)); + dt_node_type_assign(dnp, DT_STR_CTFP(dtp), DT_STR_TYPE(dtp), B_FALSE); return (dnp); } @@ -1337,7 +1373,8 @@ dt_node_type(dt_decl_t *ddp) dnp = dt_node_alloc(DT_NODE_TYPE); dnp->dn_op = DT_TOK_IDENT; dnp->dn_string = name; - dt_node_type_assign(dnp, dtt.dtt_ctfp, dtt.dtt_type); + + dt_node_type_assign(dnp, dtt.dtt_ctfp, dtt.dtt_type, dtt.dtt_flags); if (dtt.dtt_ctfp == dtp->dt_cdefs->dm_ctfp || dtt.dtt_ctfp == dtp->dt_ddefs->dm_ctfp) @@ -1581,7 +1618,8 @@ dt_node_decl(void) bzero(&idn, sizeof (dt_node_t)); if (idp != NULL && idp->di_type != CTF_ERR) - dt_node_type_assign(&idn, idp->di_ctfp, idp->di_type); + dt_node_type_assign(&idn, idp->di_ctfp, idp->di_type, + B_FALSE); else if (idp != NULL) (void) dt_ident_cook(&idn, idp, NULL); @@ -1791,7 +1829,7 @@ dt_node_offsetof(dt_decl_t *ddp, char *s) } bzero(&dn, sizeof (dn)); - dt_node_type_assign(&dn, dtt.dtt_ctfp, ctm.ctm_type); + dt_node_type_assign(&dn, dtt.dtt_ctfp, ctm.ctm_type, B_FALSE); if (dn.dn_flags & DT_NF_BITFIELD) { xyerror(D_OFFSETOF_BITFIELD, @@ -1847,7 +1885,8 @@ dt_node_op1(int op, dt_node_t *cp) } dt_node_type_assign(cp, dtp->dt_ddefs->dm_ctfp, - ctf_lookup_by_name(dtp->dt_ddefs->dm_ctfp, "size_t")); + ctf_lookup_by_name(dtp->dt_ddefs->dm_ctfp, "size_t"), + B_FALSE); cp->dn_kind = DT_NODE_INT; cp->dn_op = DT_TOK_INT; @@ -1925,17 +1964,17 @@ dt_node_op2(int op, dt_node_t *lp, dt_node_t *rp) case DT_TOK_LOR: dnp->dn_value = l || r; dt_node_type_assign(dnp, - DT_INT_CTFP(dtp), DT_INT_TYPE(dtp)); + DT_INT_CTFP(dtp), DT_INT_TYPE(dtp), B_FALSE); break; case DT_TOK_LXOR: dnp->dn_value = (l != 0) ^ (r != 0); dt_node_type_assign(dnp, - DT_INT_CTFP(dtp), DT_INT_TYPE(dtp)); + DT_INT_CTFP(dtp), DT_INT_TYPE(dtp), B_FALSE); break; case DT_TOK_LAND: dnp->dn_value = l && r; dt_node_type_assign(dnp, - DT_INT_CTFP(dtp), DT_INT_TYPE(dtp)); + DT_INT_CTFP(dtp), DT_INT_TYPE(dtp), B_FALSE); break; case DT_TOK_BOR: dnp->dn_value = l | r; @@ -1952,12 +1991,12 @@ dt_node_op2(int op, dt_node_t *lp, dt_node_t *rp) case DT_TOK_EQU: dnp->dn_value = l == r; dt_node_type_assign(dnp, - DT_INT_CTFP(dtp), DT_INT_TYPE(dtp)); + DT_INT_CTFP(dtp), DT_INT_TYPE(dtp), B_FALSE); break; case DT_TOK_NEQ: dnp->dn_value = l != r; dt_node_type_assign(dnp, - DT_INT_CTFP(dtp), DT_INT_TYPE(dtp)); + DT_INT_CTFP(dtp), DT_INT_TYPE(dtp), B_FALSE); break; case DT_TOK_LT: dt_node_promote(lp, rp, dnp); @@ -1966,7 +2005,7 @@ dt_node_op2(int op, dt_node_t *lp, dt_node_t *rp) else dnp->dn_value = l < r; dt_node_type_assign(dnp, - DT_INT_CTFP(dtp), DT_INT_TYPE(dtp)); + DT_INT_CTFP(dtp), DT_INT_TYPE(dtp), B_FALSE); break; case DT_TOK_LE: dt_node_promote(lp, rp, dnp); @@ -1975,7 +2014,7 @@ dt_node_op2(int op, dt_node_t *lp, dt_node_t *rp) else dnp->dn_value = l <= r; dt_node_type_assign(dnp, - DT_INT_CTFP(dtp), DT_INT_TYPE(dtp)); + DT_INT_CTFP(dtp), DT_INT_TYPE(dtp), B_FALSE); break; case DT_TOK_GT: dt_node_promote(lp, rp, dnp); @@ -1984,7 +2023,7 @@ dt_node_op2(int op, dt_node_t *lp, dt_node_t *rp) else dnp->dn_value = l > r; dt_node_type_assign(dnp, - DT_INT_CTFP(dtp), DT_INT_TYPE(dtp)); + DT_INT_CTFP(dtp), DT_INT_TYPE(dtp), B_FALSE); break; case DT_TOK_GE: dt_node_promote(lp, rp, dnp); @@ -1993,7 +2032,7 @@ dt_node_op2(int op, dt_node_t *lp, dt_node_t *rp) else dnp->dn_value = l >= r; dt_node_type_assign(dnp, - DT_INT_CTFP(dtp), DT_INT_TYPE(dtp)); + DT_INT_CTFP(dtp), DT_INT_TYPE(dtp), B_FALSE); break; case DT_TOK_LSH: dnp->dn_value = l << r; @@ -2234,7 +2273,7 @@ dt_node_inline(dt_node_t *expr) * until we have successfully cooked the right-hand expression, below. */ dnp = dt_node_alloc(DT_NODE_INLINE); - dt_node_type_assign(dnp, dtt.dtt_ctfp, dtt.dtt_type); + dt_node_type_assign(dnp, dtt.dtt_ctfp, dtt.dtt_type, B_FALSE); dt_node_attr_assign(dnp, _dtrace_defattr); if (dt_node_is_void(dnp)) { @@ -2389,7 +2428,8 @@ dt_node_member(dt_decl_t *ddp, char *name, dt_node_t *expr) dnp->dn_membexpr = expr; if (ddp != NULL) - dt_node_type_assign(dnp, dtt.dtt_ctfp, dtt.dtt_type); + dt_node_type_assign(dnp, dtt.dtt_ctfp, dtt.dtt_type, + dtt.dtt_flags); return (dnp); } @@ -2420,10 +2460,10 @@ dt_node_xlator(dt_decl_t *ddp, dt_decl_t *sdp, char *name, dt_node_t *members) } bzero(&sn, sizeof (sn)); - dt_node_type_assign(&sn, src.dtt_ctfp, src.dtt_type); + dt_node_type_assign(&sn, src.dtt_ctfp, src.dtt_type, B_FALSE); bzero(&dn, sizeof (dn)); - dt_node_type_assign(&dn, dst.dtt_ctfp, dst.dtt_type); + dt_node_type_assign(&dn, dst.dtt_ctfp, dst.dtt_type, B_FALSE); if (dt_xlator_lookup(dtp, &sn, &dn, DT_XLATE_EXACT) != NULL) { xyerror(D_XLATE_REDECL, @@ -2669,7 +2709,7 @@ dt_xcook_ident(dt_node_t *dnp, dt_idhash_t *dhp, uint_t idkind, int create) attr = dt_ident_cook(dnp, idp, NULL); else { dt_node_type_assign(dnp, - DT_DYN_CTFP(dtp), DT_DYN_TYPE(dtp)); + DT_DYN_CTFP(dtp), DT_DYN_TYPE(dtp), B_FALSE); attr = idp->di_attr; } @@ -2745,7 +2785,8 @@ dt_xcook_ident(dt_node_t *dnp, dt_idhash_t *dhp, uint_t idkind, int create) dnp->dn_ident = idp; dnp->dn_flags |= DT_NF_LVALUE; - dt_node_type_assign(dnp, dtt.dtt_ctfp, dtt.dtt_type); + dt_node_type_assign(dnp, dtt.dtt_ctfp, dtt.dtt_type, + dtt.dtt_flags); dt_node_attr_assign(dnp, _dtrace_symattr); if (uref) { @@ -2793,7 +2834,7 @@ dt_xcook_ident(dt_node_t *dnp, dt_idhash_t *dhp, uint_t idkind, int create) attr = dt_ident_cook(dnp, idp, NULL); else { dt_node_type_assign(dnp, - DT_DYN_CTFP(dtp), DT_DYN_TYPE(dtp)); + DT_DYN_CTFP(dtp), DT_DYN_TYPE(dtp), B_FALSE); attr = idp->di_attr; } @@ -2896,7 +2937,8 @@ dt_cook_op1(dt_node_t *dnp, uint_t idflags) xyerror(D_TYPE_ERR, "failed to lookup int64_t\n"); dt_ident_type_assign(cp->dn_ident, dtt.dtt_ctfp, dtt.dtt_type); - dt_node_type_assign(cp, dtt.dtt_ctfp, dtt.dtt_type); + dt_node_type_assign(cp, dtt.dtt_ctfp, dtt.dtt_type, + dtt.dtt_flags); } if (cp->dn_kind == DT_NODE_VAR) @@ -2913,7 +2955,8 @@ dt_cook_op1(dt_node_t *dnp, uint_t idflags) dnp->dn_ident = &dxp->dx_souid; dt_node_type_assign(dnp, - dnp->dn_ident->di_ctfp, dnp->dn_ident->di_type); + dnp->dn_ident->di_ctfp, dnp->dn_ident->di_type, + cp->dn_flags & DT_NF_USERLAND); break; } @@ -2933,7 +2976,8 @@ dt_cook_op1(dt_node_t *dnp, uint_t idflags) "cannot dereference non-pointer type\n"); } - dt_node_type_assign(dnp, cp->dn_ctfp, type); + dt_node_type_assign(dnp, cp->dn_ctfp, type, + cp->dn_flags & DT_NF_USERLAND); base = ctf_type_resolve(cp->dn_ctfp, type); kind = ctf_type_kind(cp->dn_ctfp, base); @@ -2990,7 +3034,8 @@ dt_cook_op1(dt_node_t *dnp, uint_t idflags) xyerror(D_OP_SCALAR, "operator %s requires an operand " "of scalar type\n", opstr(dnp->dn_op)); } - dt_node_type_assign(dnp, DT_INT_CTFP(dtp), DT_INT_TYPE(dtp)); + dt_node_type_assign(dnp, DT_INT_CTFP(dtp), DT_INT_TYPE(dtp), + B_FALSE); break; case DT_TOK_ADDROF: @@ -3023,10 +3068,8 @@ dt_cook_op1(dt_node_t *dnp, uint_t idflags) dt_node_type_name(cp, n, sizeof (n))); } - dt_node_type_assign(dnp, dtt.dtt_ctfp, dtt.dtt_type); - - if (cp->dn_flags & DT_NF_USERLAND) - dnp->dn_flags |= DT_NF_USERLAND; + dt_node_type_assign(dnp, dtt.dtt_ctfp, dtt.dtt_type, + cp->dn_flags & DT_NF_USERLAND); break; case DT_TOK_SIZEOF: @@ -3041,7 +3084,8 @@ dt_cook_op1(dt_node_t *dnp, uint_t idflags) } dt_node_type_assign(dnp, dtp->dt_ddefs->dm_ctfp, - ctf_lookup_by_name(dtp->dt_ddefs->dm_ctfp, "size_t")); + ctf_lookup_by_name(dtp->dt_ddefs->dm_ctfp, "size_t"), + B_FALSE); break; case DT_TOK_STRINGOF: @@ -3051,7 +3095,8 @@ dt_cook_op1(dt_node_t *dnp, uint_t idflags) "cannot apply stringof to a value of type %s\n", dt_node_type_name(cp, n, sizeof (n))); } - dt_node_type_assign(dnp, DT_STR_CTFP(dtp), DT_STR_TYPE(dtp)); + dt_node_type_assign(dnp, DT_STR_CTFP(dtp), DT_STR_TYPE(dtp), + cp->dn_flags & DT_NF_USERLAND); break; case DT_TOK_PREINC: @@ -3244,7 +3289,8 @@ dt_cook_op2(dt_node_t *dnp, uint_t idflags) "of scalar type\n", opstr(op)); } - dt_node_type_assign(dnp, DT_INT_CTFP(dtp), DT_INT_TYPE(dtp)); + dt_node_type_assign(dnp, DT_INT_CTFP(dtp), DT_INT_TYPE(dtp), + B_FALSE); dt_node_attr_assign(dnp, dt_attr_min(lp->dn_attr, rp->dn_attr)); break; @@ -3288,7 +3334,8 @@ dt_cook_op2(dt_node_t *dnp, uint_t idflags) rp->dn_op = DT_TOK_INT; rp->dn_value = (intmax_t)val; - dt_node_type_assign(rp, lp->dn_ctfp, lp->dn_type); + dt_node_type_assign(rp, lp->dn_ctfp, lp->dn_type, + B_FALSE); dt_node_attr_assign(rp, _dtrace_symattr); } @@ -3320,7 +3367,8 @@ dt_cook_op2(dt_node_t *dnp, uint_t idflags) dt_node_type_name(rp, n2, sizeof (n2))); } - dt_node_type_assign(dnp, DT_INT_CTFP(dtp), DT_INT_TYPE(dtp)); + dt_node_type_assign(dnp, DT_INT_CTFP(dtp), DT_INT_TYPE(dtp), + B_FALSE); dt_node_attr_assign(dnp, dt_attr_min(lp->dn_attr, rp->dn_attr)); break; @@ -3368,7 +3416,7 @@ dt_cook_op2(dt_node_t *dnp, uint_t idflags) dt_node_type_name(rp, n2, sizeof (n2))); } - dt_node_type_assign(dnp, ctfp, type); + dt_node_type_assign(dnp, ctfp, type, B_FALSE); dt_node_attr_assign(dnp, dt_attr_min(lp->dn_attr, rp->dn_attr)); if (uref) @@ -3509,7 +3557,7 @@ dt_cook_op2(dt_node_t *dnp, uint_t idflags) */ if (lp->dn_kind == DT_NODE_VAR && dt_ident_unref(lp->dn_ident)) { - dt_node_type_assign(lp, ctfp, type); + dt_node_type_assign(lp, ctfp, type, B_FALSE); dt_ident_type_assign(lp->dn_ident, ctfp, type); if (uref) { @@ -3723,7 +3771,7 @@ asgn_common: type = ctf_type_resolve(ctfp, m.ctm_type); kind = ctf_type_kind(ctfp, type); - dt_node_type_assign(dnp, ctfp, m.ctm_type); + dt_node_type_assign(dnp, ctfp, m.ctm_type, B_FALSE); dt_node_attr_assign(dnp, lp->dn_attr); if (op == DT_TOK_PTR && (kind != CTF_K_ARRAY || @@ -3849,7 +3897,8 @@ asgn_common: } dnp->dn_ident = dt_xlator_ident(dxp, lp->dn_ctfp, lp->dn_type); - dt_node_type_assign(dnp, DT_DYN_CTFP(dtp), DT_DYN_TYPE(dtp)); + dt_node_type_assign(dnp, DT_DYN_CTFP(dtp), DT_DYN_TYPE(dtp), + B_FALSE); dt_node_attr_assign(dnp, dt_attr_min(rp->dn_attr, dnp->dn_ident->di_attr)); break; @@ -4014,7 +4063,7 @@ dt_cook_op3(dt_node_t *dnp, uint_t idflags) "used in a conditional context\n"); } - dt_node_type_assign(dnp, ctfp, type); + dt_node_type_assign(dnp, ctfp, type, B_FALSE); dt_node_attr_assign(dnp, dt_attr_min(dnp->dn_expr->dn_attr, dt_attr_min(lp->dn_attr, rp->dn_attr))); @@ -4047,7 +4096,8 @@ dt_cook_aggregation(dt_node_t *dnp, uint_t idflags) dt_node_attr_assign(dnp, dt_ident_cook(dnp, dnp->dn_ident, &dnp->dn_aggtup)); } else { - dt_node_type_assign(dnp, DT_DYN_CTFP(dtp), DT_DYN_TYPE(dtp)); + dt_node_type_assign(dnp, DT_DYN_CTFP(dtp), DT_DYN_TYPE(dtp), + B_FALSE); dt_node_attr_assign(dnp, dnp->dn_ident->di_attr); } @@ -4249,7 +4299,8 @@ dt_cook_xlator(dt_node_t *dnp, uint_t idflags) } (void) dt_node_cook(mnp, DT_IDFLG_REF); - dt_node_type_assign(mnp, dxp->dx_dst_ctfp, ctm.ctm_type); + dt_node_type_assign(mnp, dxp->dx_dst_ctfp, ctm.ctm_type, + B_FALSE); attr = dt_attr_min(attr, mnp->dn_attr); if (dt_node_is_argcompat(mnp, mnp->dn_membexpr) == 0) { @@ -4268,7 +4319,7 @@ dt_cook_xlator(dt_node_t *dnp, uint_t idflags) dxp->dx_souid.di_attr = attr; dxp->dx_ptrid.di_attr = attr; - dt_node_type_assign(dnp, DT_DYN_CTFP(dtp), DT_DYN_TYPE(dtp)); + dt_node_type_assign(dnp, DT_DYN_CTFP(dtp), DT_DYN_TYPE(dtp), B_FALSE); dt_node_attr_assign(dnp, _dtrace_defattr); return (dnp); @@ -4561,7 +4612,9 @@ dt_node_diftype(dtrace_hdl_t *dtp, const dt_node_t *dnp, dtrace_diftype_t *tp) ctf_type_resolve(dnp->dn_ctfp, dnp->dn_type)); } - tp->dtdt_flags = (dnp->dn_flags & DT_NF_REF) ? DIF_TF_BYREF : 0; + tp->dtdt_flags = (dnp->dn_flags & DT_NF_REF) ? + (dnp->dn_flags & DT_NF_USERLAND) ? DIF_TF_BYUREF : + DIF_TF_BYREF : 0; tp->dtdt_pad = 0; tp->dtdt_size = ctf_type_size(dnp->dn_ctfp, dnp->dn_type); } diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_parser.h b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_parser.h index 6064efb..38f21c9 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_parser.h +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_parser.h @@ -22,12 +22,14 @@ * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ +/* + * Copyright (c) 2013 by Delphix. All rights reserved. + * Copyright (c) 2013 Joyent, Inc. All rights reserved. + */ #ifndef _DT_PARSER_H #define _DT_PARSER_H -#pragma ident "%Z%%M% %I% %E% SMI" - #include <sys/types.h> #include <sys/dtrace.h> @@ -223,7 +225,7 @@ extern void dt_node_list_free(dt_node_t **); extern void dt_node_link_free(dt_node_t **); extern void dt_node_attr_assign(dt_node_t *, dtrace_attribute_t); -extern void dt_node_type_assign(dt_node_t *, ctf_file_t *, ctf_id_t); +extern void dt_node_type_assign(dt_node_t *, ctf_file_t *, ctf_id_t, boolean_t); extern void dt_node_type_propagate(const dt_node_t *, dt_node_t *); extern const char *dt_node_type_name(const dt_node_t *, char *, size_t); extern size_t dt_node_type_size(const dt_node_t *); diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pid.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pid.c index b145818..c865a2d 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pid.c +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pid.c @@ -23,6 +23,9 @@ * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ +/* + * Copyright (c) 2013, Joyent, Inc. All rights reserved. + */ #include <assert.h> #include <strings.h> @@ -35,6 +38,7 @@ #endif #include <libgen.h> #include <stddef.h> +#include <sys/sysmacros.h> #include <dt_impl.h> #include <dt_program.h> @@ -43,6 +47,7 @@ #if !defined(sun) #include <libproc_compat.h> #endif +#include <dt_module.h> typedef struct dt_pid_probe { dtrace_hdl_t *dpp_dtp; @@ -827,3 +832,170 @@ dt_pid_create_probes_module(dtrace_hdl_t *dtp, dt_proc_t *dpr) return (ret); } + +/* + * libdtrace has a backroom deal with us to ask us for type information on + * behalf of pid provider probes when fasttrap doesn't return any type + * information. Instead we'll look up the module and see if there is type + * information available. However, if there is no type information available due + * to a lack of CTF data, then we want to make sure that DTrace still carries on + * in face of that. As such we don't have a meaningful exit code about failure. + * We emit information about why we failed to the dtrace debug log so someone + * can figure it out by asking nicely for DTRACE_DEBUG. + */ +void +dt_pid_get_types(dtrace_hdl_t *dtp, const dtrace_probedesc_t *pdp, + dtrace_argdesc_t *adp, int *nargs) +{ + dt_module_t *dmp; + ctf_file_t *fp; + ctf_funcinfo_t f; + ctf_id_t argv[32]; + GElf_Sym sym; +#if defined(sun) + prsyminfo_t si; +#else + void *si; +#endif + struct ps_prochandle *p; + int i, args; + char buf[DTRACE_ARGTYPELEN]; + const char *mptr; + char *eptr; + int ret = 0; + int argc = sizeof (argv) / sizeof (ctf_id_t); + Lmid_t lmid; + + /* Set up a potential outcome */ + args = *nargs; + *nargs = 0; + + /* + * If we don't have an entry or return probe then we can just stop right + * now as we don't have arguments for offset probes. + */ + if (strcmp(pdp->dtpd_name, "entry") != 0 && + strcmp(pdp->dtpd_name, "return") != 0) + return; + + dmp = dt_module_create(dtp, pdp->dtpd_provider); + if (dmp == NULL) { + dt_dprintf("failed to find module for %s\n", + pdp->dtpd_provider); + return; + } + if (dt_module_load(dtp, dmp) != 0) { + dt_dprintf("failed to load module for %s\n", + pdp->dtpd_provider); + return; + } + + /* + * We may be working with a module that doesn't have ctf. If that's the + * case then we just return now and move on with life. + */ + fp = dt_module_getctflib(dtp, dmp, pdp->dtpd_mod); + if (fp == NULL) { + dt_dprintf("no ctf container for %s\n", + pdp->dtpd_mod); + return; + } + p = dt_proc_grab(dtp, dmp->dm_pid, 0, PGRAB_RDONLY | PGRAB_FORCE); + if (p == NULL) { + dt_dprintf("failed to grab pid\n"); + return; + } + dt_proc_lock(dtp, p); + + /* + * Check to see if the D module has a link map ID and separate that out + * for properly interrogating libproc. + */ + if ((mptr = strchr(pdp->dtpd_mod, '`')) != NULL) { + if (strlen(pdp->dtpd_mod) < 3) { + dt_dprintf("found weird modname with linkmap, " + "aborting: %s\n", pdp->dtpd_mod); + goto out; + } + if (pdp->dtpd_mod[0] != 'L' || pdp->dtpd_mod[1] != 'M') { + dt_dprintf("missing leading 'LM', " + "aborting: %s\n", pdp->dtpd_mod); + goto out; + } + errno = 0; + lmid = strtol(pdp->dtpd_mod + 2, &eptr, 16); + if (errno == ERANGE || eptr != mptr) { + dt_dprintf("failed to parse out lmid, aborting: %s\n", + pdp->dtpd_mod); + goto out; + } + mptr++; + } else { + mptr = pdp->dtpd_mod; + lmid = 0; + } + + if (Pxlookup_by_name(p, lmid, mptr, pdp->dtpd_func, + &sym, &si) != 0) { + dt_dprintf("failed to find function %s in %s`%s\n", + pdp->dtpd_func, pdp->dtpd_provider, pdp->dtpd_mod); + goto out; + } +#if defined(sun) + if (ctf_func_info(fp, si.prs_id, &f) == CTF_ERR) { + dt_dprintf("failed to get ctf information for %s in %s`%s\n", + pdp->dtpd_func, pdp->dtpd_provider, pdp->dtpd_mod); + goto out; + } +#endif + + (void) snprintf(buf, sizeof (buf), "%s`%s", pdp->dtpd_provider, + pdp->dtpd_mod); + + if (strcmp(pdp->dtpd_name, "return") == 0) { + if (args < 2) + goto out; + + bzero(adp, sizeof (dtrace_argdesc_t)); + adp->dtargd_ndx = 0; + adp->dtargd_id = pdp->dtpd_id; + adp->dtargd_mapping = adp->dtargd_ndx; + /* + * We explicitly leave out the library here, we only care that + * it is some int. We are assuming that there is no ctf + * container in here that is lying about what an int is. + */ + (void) snprintf(adp->dtargd_native, DTRACE_ARGTYPELEN, + "user %s`%s", pdp->dtpd_provider, "int"); + adp++; + bzero(adp, sizeof (dtrace_argdesc_t)); + adp->dtargd_ndx = 1; + adp->dtargd_id = pdp->dtpd_id; + adp->dtargd_mapping = adp->dtargd_ndx; + ret = snprintf(adp->dtargd_native, DTRACE_ARGTYPELEN, + "userland "); + (void) ctf_type_qname(fp, f.ctc_return, adp->dtargd_native + + ret, DTRACE_ARGTYPELEN - ret, buf); + *nargs = 2; +#if defined(sun) + } else { + if (ctf_func_args(fp, si.prs_id, argc, argv) == CTF_ERR) + goto out; + + *nargs = MIN(args, f.ctc_argc); + for (i = 0; i < *nargs; i++, adp++) { + bzero(adp, sizeof (dtrace_argdesc_t)); + adp->dtargd_ndx = i; + adp->dtargd_id = pdp->dtpd_id; + adp->dtargd_mapping = adp->dtargd_ndx; + ret = snprintf(adp->dtargd_native, DTRACE_ARGTYPELEN, + "userland "); + (void) ctf_type_qname(fp, argv[i], adp->dtargd_native + + ret, DTRACE_ARGTYPELEN - ret, buf); + } +#endif + } +out: + dt_proc_unlock(dtp, p); + dt_proc_release(dtp, p); +} diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pid.h b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pid.h index 886e33d..4bf39c8 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pid.h +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pid.h @@ -24,12 +24,13 @@ * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ +/* + * Copyright (c) 2013, Joyent, Inc. All rights reserved. + */ #ifndef _DT_PID_H #define _DT_PID_H -#pragma ident "%Z%%M% %I% %E% SMI" - #include <libproc.h> #include <sys/fasttrap.h> #include <dt_impl.h> @@ -57,6 +58,9 @@ extern int dt_pid_create_offset_probe(struct ps_prochandle *, dtrace_hdl_t *, extern int dt_pid_create_glob_offset_probes(struct ps_prochandle *, dtrace_hdl_t *, fasttrap_probe_spec_t *, const GElf_Sym *, const char *); +extern void dt_pid_get_types(dtrace_hdl_t *, const dtrace_probedesc_t *, + dtrace_argdesc_t *, int *); + #ifdef __cplusplus } #endif diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_print.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_print.c index ccfa3da..fb8ea16 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_print.c +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_print.c @@ -647,12 +647,16 @@ dtrace_print(dtrace_hdl_t *dtp, FILE *fp, const char *typename, dt_printarg_t pa; ctf_id_t id; dt_module_t *dmp; + ctf_file_t *ctfp; + int libid; /* * Split the fully-qualified type ID (module`id). This should * always be the format, but if for some reason we don't find the * expected value, return 0 to fall back to the generic trace() - * behavior. + * behavior. In the case of userland CTF modules this will actually be + * of the format (module`lib`id). This is due to the fact that those + * modules have multiple CTF containers which `lib` identifies. */ for (s = typename; *s != '\0' && *s != '`'; s++) ; @@ -663,6 +667,20 @@ dtrace_print(dtrace_hdl_t *dtp, FILE *fp, const char *typename, object = alloca(s - typename + 1); bcopy(typename, object, s - typename); object[s - typename] = '\0'; + dmp = dt_module_lookup_by_name(dtp, object); + if (dmp == NULL) + return (0); + + if (dmp->dm_pid != 0) { + libid = atoi(s + 1); + s = strchr(s + 1, '`'); + if (s == NULL || libid > dmp->dm_nctflibs) + return (0); + ctfp = dmp->dm_libctfp[libid]; + } else { + ctfp = dt_module_getctf(dtp, dmp); + } + id = atoi(s + 1); /* @@ -670,16 +688,13 @@ dtrace_print(dtrace_hdl_t *dtp, FILE *fp, const char *typename, * wrong and we can't resolve the ID, bail out and let trace() do the * work. */ - dmp = dt_module_lookup_by_name(dtp, object); - if (dmp == NULL || ctf_type_kind(dt_module_getctf(dtp, dmp), - id) == CTF_ERR) { + if (ctfp == NULL || ctf_type_kind(ctfp, id) == CTF_ERR) return (0); - } /* setup the print structure and kick off the main print routine */ pa.pa_dtp = dtp; pa.pa_addr = addr; - pa.pa_ctfp = dt_module_getctf(dtp, dmp); + pa.pa_ctfp = ctfp; pa.pa_nest = 0; pa.pa_depth = 0; pa.pa_file = fp; diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_printf.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_printf.c index 24682b2..9d4403c 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_printf.c +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_printf.c @@ -21,8 +21,8 @@ /* * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2011, Joyent, Inc. All rights reserved. - * Copyright (c) 2012 by Delphix. All rights reserved. + * Copyright (c) 2013, Joyent, Inc. All rights reserved. + * Copyright (c) 2013 by Delphix. All rights reserved. */ #if defined(sun) @@ -1070,7 +1070,7 @@ dt_printf_validate(dt_pfargv_t *pfv, uint_t flags, xyerror(D_TYPE_ERR, "failed to lookup agg type %s\n", aggtype); bzero(&aggnode, sizeof (aggnode)); - dt_node_type_assign(&aggnode, dtt.dtt_ctfp, dtt.dtt_type); + dt_node_type_assign(&aggnode, dtt.dtt_ctfp, dtt.dtt_type, B_FALSE); for (i = 0, j = 0; i < pfv->pfv_argc; i++, pfd = pfd->pfd_next) { const dt_pfconv_t *pfc = pfd->pfd_conv; diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_provider.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_provider.c index 188ce0e..0f1bfe0 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_provider.c +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_provider.c @@ -23,8 +23,9 @@ * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ - -#pragma ident "%Z%%M% %I% %E% SMI" +/* + * Copyright (c) 2013, Joyent, Inc. All rights reserved. + */ #include <sys/types.h> #if defined(sun) @@ -45,6 +46,8 @@ #include <dt_module.h> #include <dt_string.h> #include <dt_list.h> +#include <dt_pid.h> +#include <dtrace.h> static dt_provider_t * dt_provider_insert(dtrace_hdl_t *dtp, dt_provider_t *pvp, uint_t h) @@ -273,6 +276,21 @@ dt_probe_discover(dt_provider_t *pvp, const dtrace_probedesc_t *pdp) nc++; /* + * The pid provider believes in giving the kernel a break. No reason to + * give the kernel all the ctf containers that we're keeping ourselves + * just to get it back from it. So if we're coming from a pid provider + * probe and the kernel gave us no argument information we'll get some + * here. If for some crazy reason the kernel knows about our userland + * types then we just ignore this. + */ + if (xc == 0 && nc == 0 && + strncmp(pvp->pv_desc.dtvd_name, "pid", 3) == 0) { + nc = adc; + dt_pid_get_types(dtp, pdp, adv, &nc); + xc = nc; + } + + /* * Now that we have discovered the number of native and translated * arguments from the argument descriptions, allocate a new probe ident * and corresponding dt_probe_t and hash it into the provider. @@ -318,7 +336,8 @@ dt_probe_discover(dt_provider_t *pvp, const dtrace_probedesc_t *pdp) dtt.dtt_type = CTF_ERR; } else { dt_node_type_assign(prp->pr_nargv[adp->dtargd_mapping], - dtt.dtt_ctfp, dtt.dtt_type); + dtt.dtt_ctfp, dtt.dtt_type, + dtt.dtt_flags & DTT_FL_USER ? B_TRUE : B_FALSE); } if (dtt.dtt_type != CTF_ERR && (adp->dtargd_xlate[0] == '\0' || @@ -337,7 +356,7 @@ dt_probe_discover(dt_provider_t *pvp, const dtrace_probedesc_t *pdp) dtt.dtt_type = CTF_ERR; } else { dt_node_type_assign(prp->pr_xargv[i], - dtt.dtt_ctfp, dtt.dtt_type); + dtt.dtt_ctfp, dtt.dtt_type, B_FALSE); } prp->pr_mapping[i] = adp->dtargd_mapping; @@ -638,7 +657,7 @@ dt_probe_tag(dt_probe_t *prp, uint_t argn, dt_node_t *dnp) bzero(dnp, sizeof (dt_node_t)); dnp->dn_kind = DT_NODE_TYPE; - dt_node_type_assign(dnp, dtt.dtt_ctfp, dtt.dtt_type); + dt_node_type_assign(dnp, dtt.dtt_ctfp, dtt.dtt_type, B_FALSE); dt_node_attr_assign(dnp, _dtrace_defattr); return (dnp); diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_xlator.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_xlator.c index 7ac0cc4..74bd487 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_xlator.c +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_xlator.c @@ -23,8 +23,10 @@ * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ - -#pragma ident "%Z%%M% %I% %E% SMI" +/* + * Copyright (c) 2013 by Delphix. All rights reserved. + * Copyright (c) 2013 Joyent, Inc. All rights reserved. + */ #include <strings.h> #include <assert.h> @@ -69,7 +71,7 @@ dt_xlator_create_member(const char *name, ctf_id_t type, ulong_t off, void *arg) enp->dn_op = DT_TOK_XLATE; enp->dn_xlator = dxp; enp->dn_xmember = mnp; - dt_node_type_assign(enp, dxp->dx_dst_ctfp, type); + dt_node_type_assign(enp, dxp->dx_dst_ctfp, type, B_FALSE); /* * For the member itself, we use a DT_NODE_MEMBER as usual with the @@ -83,7 +85,7 @@ dt_xlator_create_member(const char *name, ctf_id_t type, ulong_t off, void *arg) mnp->dn_membname = strdup(name); mnp->dn_membexpr = enp; - dt_node_type_assign(mnp, dxp->dx_dst_ctfp, type); + dt_node_type_assign(mnp, dxp->dx_dst_ctfp, type, B_FALSE); if (mnp->dn_membname == NULL) return (dt_set_errno(dtp, EDT_NOMEM)); @@ -318,7 +320,8 @@ dt_xlator_lookup(dtrace_hdl_t *dtp, dt_node_t *src, dt_node_t *dst, int flags) for (dxp = dt_list_next(&dtp->dt_xlators); dxp != NULL; dxp = dt_list_next(dxp)) { - dt_node_type_assign(&xn, dxp->dx_src_ctfp, dxp->dx_src_type); + dt_node_type_assign(&xn, dxp->dx_src_ctfp, dxp->dx_src_type, + B_FALSE); if (ctf_type_compat(dxp->dx_dst_ctfp, dxp->dx_dst_base, dst_ctfp, dst_base) && dt_node_is_argcompat(src, &xn)) goto out; diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dtrace.h b/cddl/contrib/opensolaris/lib/libdtrace/common/dtrace.h index b2e3108..6f88e6d 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dtrace.h +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dtrace.h @@ -25,7 +25,8 @@ */ /* - * Copyright (c) 2011, Joyent, Inc. All rights reserved. + * Copyright (c) 2013 by Delphix. All rights reserved. + * Copyright (c) 2013, Joyent, Inc. All rights reserved. */ #ifndef _DTRACE_H @@ -356,6 +357,12 @@ extern int dtrace_handle_setopt(dtrace_hdl_t *, #define DTRACE_A_PERCPU 0x0001 #define DTRACE_A_KEEPDELTA 0x0002 #define DTRACE_A_ANONYMOUS 0x0004 +#define DTRACE_A_TOTAL 0x0008 +#define DTRACE_A_MINMAXBIN 0x0010 +#define DTRACE_A_HASNEGATIVES 0x0020 +#define DTRACE_A_HASPOSITIVES 0x0040 + +#define DTRACE_AGGZOOM_MAX 0.95 /* height of max bar */ #define DTRACE_AGGWALK_ERROR -1 /* error while processing */ #define DTRACE_AGGWALK_NEXT 0 /* proceed to next element */ @@ -376,6 +383,10 @@ struct dtrace_aggdata { caddr_t dtada_delta; /* delta data, if available */ caddr_t *dtada_percpu; /* per CPU data, if avail */ caddr_t *dtada_percpu_delta; /* per CPU delta, if avail */ + int64_t dtada_total; /* per agg total, if avail */ + uint16_t dtada_minbin; /* minimum bin, if avail */ + uint16_t dtada_maxbin; /* maximum bin, if avail */ + uint32_t dtada_flags; /* flags */ }; typedef int dtrace_aggregate_f(const dtrace_aggdata_t *, void *); @@ -495,8 +506,11 @@ typedef struct dtrace_typeinfo { const char *dtt_object; /* object containing type */ ctf_file_t *dtt_ctfp; /* CTF container handle */ ctf_id_t dtt_type; /* CTF type identifier */ + uint_t dtt_flags; /* Misc. flags */ } dtrace_typeinfo_t; +#define DTT_FL_USER 0x1 /* user type */ + extern int dtrace_lookup_by_type(dtrace_hdl_t *, const char *, const char *, dtrace_typeinfo_t *); |