dsdebug.c revision 298714
1/******************************************************************************
2 *
3 * Module Name: dsdebug - Parser/Interpreter interface - debugging
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2016, Intel Corp.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 *    notice, this list of conditions, and the following disclaimer,
16 *    without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 *    substantially similar to the "NO WARRANTY" disclaimer below
19 *    ("Disclaimer") and any redistribution must be conditioned upon
20 *    including a substantially similar Disclaimer requirement for further
21 *    binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 *    of any contributors may be used to endorse or promote products derived
24 *    from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44#include <contrib/dev/acpica/include/acpi.h>
45#include <contrib/dev/acpica/include/accommon.h>
46#include <contrib/dev/acpica/include/acdispat.h>
47#include <contrib/dev/acpica/include/acnamesp.h>
48#include <contrib/dev/acpica/include/acdisasm.h>
49#include <contrib/dev/acpica/include/acinterp.h>
50
51
52#define _COMPONENT          ACPI_DISPATCHER
53        ACPI_MODULE_NAME    ("dsdebug")
54
55
56#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
57
58/* Local prototypes */
59
60static void
61AcpiDsPrintNodePathname (
62    ACPI_NAMESPACE_NODE     *Node,
63    const char              *Message);
64
65
66/*******************************************************************************
67 *
68 * FUNCTION:    AcpiDsPrintNodePathname
69 *
70 * PARAMETERS:  Node            - Object
71 *              Message         - Prefix message
72 *
73 * DESCRIPTION: Print an object's full namespace pathname
74 *              Manages allocation/freeing of a pathname buffer
75 *
76 ******************************************************************************/
77
78static void
79AcpiDsPrintNodePathname (
80    ACPI_NAMESPACE_NODE     *Node,
81    const char              *Message)
82{
83    ACPI_BUFFER             Buffer;
84    ACPI_STATUS             Status;
85
86
87    ACPI_FUNCTION_TRACE (DsPrintNodePathname);
88
89    if (!Node)
90    {
91        ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DISPATCH, "[NULL NAME]"));
92        return_VOID;
93    }
94
95    /* Convert handle to full pathname and print it (with supplied message) */
96
97    Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
98
99    Status = AcpiNsHandleToPathname (Node, &Buffer, TRUE);
100    if (ACPI_SUCCESS (Status))
101    {
102        if (Message)
103        {
104            ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DISPATCH, "%s ", Message));
105        }
106
107        ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DISPATCH, "[%s] (Node %p)",
108            (char *) Buffer.Pointer, Node));
109        ACPI_FREE (Buffer.Pointer);
110    }
111
112    return_VOID;
113}
114
115
116/*******************************************************************************
117 *
118 * FUNCTION:    AcpiDsDumpMethodStack
119 *
120 * PARAMETERS:  Status          - Method execution status
121 *              WalkState       - Current state of the parse tree walk
122 *              Op              - Executing parse op
123 *
124 * RETURN:      None
125 *
126 * DESCRIPTION: Called when a method has been aborted because of an error.
127 *              Dumps the method execution stack.
128 *
129 ******************************************************************************/
130
131void
132AcpiDsDumpMethodStack (
133    ACPI_STATUS             Status,
134    ACPI_WALK_STATE         *WalkState,
135    ACPI_PARSE_OBJECT       *Op)
136{
137    ACPI_PARSE_OBJECT       *Next;
138    ACPI_THREAD_STATE       *Thread;
139    ACPI_WALK_STATE         *NextWalkState;
140    ACPI_NAMESPACE_NODE     *PreviousMethod = NULL;
141    ACPI_OPERAND_OBJECT     *MethodDesc;
142
143
144    ACPI_FUNCTION_TRACE (DsDumpMethodStack);
145
146    /* Ignore control codes, they are not errors */
147
148    if ((Status & AE_CODE_MASK) == AE_CODE_CONTROL)
149    {
150        return_VOID;
151    }
152
153    /* We may be executing a deferred opcode */
154
155    if (WalkState->DeferredNode)
156    {
157        ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
158            "Executing subtree for Buffer/Package/Region\n"));
159        return_VOID;
160    }
161
162    /*
163     * If there is no Thread, we are not actually executing a method.
164     * This can happen when the iASL compiler calls the interpreter
165     * to perform constant folding.
166     */
167    Thread = WalkState->Thread;
168    if (!Thread)
169    {
170        return_VOID;
171    }
172
173    /* Display exception and method name */
174
175    ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
176        "\n**** Exception %s during execution of method ",
177        AcpiFormatException (Status)));
178
179    AcpiDsPrintNodePathname (WalkState->MethodNode, NULL);
180
181    /* Display stack of executing methods */
182
183    ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DISPATCH,
184        "\n\nMethod Execution Stack:\n"));
185    NextWalkState = Thread->WalkStateList;
186
187    /* Walk list of linked walk states */
188
189    while (NextWalkState)
190    {
191        MethodDesc = NextWalkState->MethodDesc;
192        if (MethodDesc)
193        {
194            AcpiExStopTraceMethod (
195                (ACPI_NAMESPACE_NODE *) MethodDesc->Method.Node,
196                MethodDesc, WalkState);
197        }
198
199        ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
200            "    Method [%4.4s] executing: ",
201            AcpiUtGetNodeName (NextWalkState->MethodNode)));
202
203        /* First method is the currently executing method */
204
205        if (NextWalkState == WalkState)
206        {
207            if (Op)
208            {
209                /* Display currently executing ASL statement */
210
211                Next = Op->Common.Next;
212                Op->Common.Next = NULL;
213
214#ifdef ACPI_DISASSEMBLER
215                AcpiDmDisassemble (NextWalkState, Op, ACPI_UINT32_MAX);
216#endif
217                Op->Common.Next = Next;
218            }
219        }
220        else
221        {
222            /*
223             * This method has called another method
224             * NOTE: the method call parse subtree is already deleted at
225             * this point, so we cannot disassemble the method invocation.
226             */
227            ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DISPATCH, "Call to method "));
228            AcpiDsPrintNodePathname (PreviousMethod, NULL);
229        }
230
231        PreviousMethod = NextWalkState->MethodNode;
232        NextWalkState = NextWalkState->Next;
233        ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DISPATCH, "\n"));
234    }
235
236    return_VOID;
237}
238
239#else
240
241void
242AcpiDsDumpMethodStack (
243    ACPI_STATUS             Status,
244    ACPI_WALK_STATE         *WalkState,
245    ACPI_PARSE_OBJECT       *Op)
246{
247    return;
248}
249
250#endif
251