1#!/usr/bin/stap
2/*
3 * Copyright (c) 2012, 2020 Oracle and/or its affiliates.  All rights reserved.
4 *
5 *  See the file LICENSE for license information.
6 *
7 * showerror.stp - Capture context about certain DB errors.
8 *
9 * This shows the stack when a variant of DB->err() is called.
10 * Specify the target process on the command line as
11 *	-p <pid> or
12 *	-c "<program> [<args>..]"
13 *
14 * This script does not require DWARF symbols in libdb.
15 */
16
17global errors, errorcount, maxlimit;
18
19probe begin
20{
21	errorcount = 0;
22	maxlimit = -1;
23	%( $# >= 2 %? maxlimit = $2 %)
24	printf("Display DB stack when ");
25	if (pid() == 0)
26		printf("an application using %s", @1)
27	else
28		printf("process %d", pid());
29	printf(" prints a DB internal error message: limit %d\n", maxlimit);
30}
31
32/* __db_err(ENV *, int errorcode, char *message, ...) */
33probe process(@1).function("__db_err").call
34{
35	message = user_string(pointer_arg(3));
36	printf("DB error %d message \"%s\"(%x,...) from:\n",
37	    int_arg(2), message, ulong_arg(4));
38	print_backtrace();
39	errors[message, backtrace()] <<< 1;
40	if (++errorcount == maxlimit)
41		exit();
42}
43
44/* __db_errx(ENV *, char *message, ...) */
45probe process(@1).function("__db_errx").call
46{
47	message = user_string(pointer_arg(2));
48	printf("DB error message \"%s\"(%x,...) parms %s from:\n", message,
49	    int_arg(3), $$parms);
50	print_backtrace();
51	errors[message, backtrace()] <<< 1;
52	if (++errorcount == maxlimit)
53		exit();
54}
55
56
57/* __env_panic(ENV *, int errorcode) */
58probe process(@1).function("__env_panic").call
59{
60	printf("DB panic with error code %d from:\n", int_arg(2));
61	print_backtrace();
62	if (++errorcount == maxlimit)
63		exit();
64}
65