123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205 |
- // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
- /******************************************************************************
- *
- * Module Name: dsdebug - Parser/Interpreter interface - debugging
- *
- * Copyright (C) 2000 - 2022, Intel Corp.
- *
- *****************************************************************************/
- #include <acpi/acpi.h>
- #include "accommon.h"
- #include "acdispat.h"
- #include "acnamesp.h"
- #ifdef ACPI_DISASSEMBLER
- #include "acdisasm.h"
- #endif
- #include "acinterp.h"
- #define _COMPONENT ACPI_DISPATCHER
- ACPI_MODULE_NAME("dsdebug")
- #if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
- /* Local prototypes */
- static void
- acpi_ds_print_node_pathname(struct acpi_namespace_node *node,
- const char *message);
- /*******************************************************************************
- *
- * FUNCTION: acpi_ds_print_node_pathname
- *
- * PARAMETERS: node - Object
- * message - Prefix message
- *
- * DESCRIPTION: Print an object's full namespace pathname
- * Manages allocation/freeing of a pathname buffer
- *
- ******************************************************************************/
- static void
- acpi_ds_print_node_pathname(struct acpi_namespace_node *node,
- const char *message)
- {
- struct acpi_buffer buffer;
- acpi_status status;
- ACPI_FUNCTION_TRACE(ds_print_node_pathname);
- if (!node) {
- ACPI_DEBUG_PRINT_RAW((ACPI_DB_DISPATCH, "[NULL NAME]"));
- return_VOID;
- }
- /* Convert handle to full pathname and print it (with supplied message) */
- buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
- status = acpi_ns_handle_to_pathname(node, &buffer, TRUE);
- if (ACPI_SUCCESS(status)) {
- if (message) {
- ACPI_DEBUG_PRINT_RAW((ACPI_DB_DISPATCH, "%s ",
- message));
- }
- ACPI_DEBUG_PRINT_RAW((ACPI_DB_DISPATCH, "[%s] (Node %p)",
- (char *)buffer.pointer, node));
- ACPI_FREE(buffer.pointer);
- }
- return_VOID;
- }
- /*******************************************************************************
- *
- * FUNCTION: acpi_ds_dump_method_stack
- *
- * PARAMETERS: status - Method execution status
- * walk_state - Current state of the parse tree walk
- * op - Executing parse op
- *
- * RETURN: None
- *
- * DESCRIPTION: Called when a method has been aborted because of an error.
- * Dumps the method execution stack.
- *
- ******************************************************************************/
- void
- acpi_ds_dump_method_stack(acpi_status status,
- struct acpi_walk_state *walk_state,
- union acpi_parse_object *op)
- {
- union acpi_parse_object *next;
- struct acpi_thread_state *thread;
- struct acpi_walk_state *next_walk_state;
- struct acpi_namespace_node *previous_method = NULL;
- union acpi_operand_object *method_desc;
- ACPI_FUNCTION_TRACE(ds_dump_method_stack);
- /* Ignore control codes, they are not errors */
- if (ACPI_CNTL_EXCEPTION(status)) {
- return_VOID;
- }
- /* We may be executing a deferred opcode */
- if (walk_state->deferred_node) {
- ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
- "Executing subtree for Buffer/Package/Region\n"));
- return_VOID;
- }
- /*
- * If there is no Thread, we are not actually executing a method.
- * This can happen when the iASL compiler calls the interpreter
- * to perform constant folding.
- */
- thread = walk_state->thread;
- if (!thread) {
- return_VOID;
- }
- /* Display exception and method name */
- ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
- "\n**** Exception %s during execution of method ",
- acpi_format_exception(status)));
- acpi_ds_print_node_pathname(walk_state->method_node, NULL);
- /* Display stack of executing methods */
- ACPI_DEBUG_PRINT_RAW((ACPI_DB_DISPATCH,
- "\n\nMethod Execution Stack:\n"));
- next_walk_state = thread->walk_state_list;
- /* Walk list of linked walk states */
- while (next_walk_state) {
- method_desc = next_walk_state->method_desc;
- if (method_desc) {
- acpi_ex_stop_trace_method((struct acpi_namespace_node *)
- method_desc->method.node,
- method_desc, walk_state);
- }
- ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
- " Method [%4.4s] executing: ",
- acpi_ut_get_node_name(next_walk_state->
- method_node)));
- /* First method is the currently executing method */
- if (next_walk_state == walk_state) {
- if (op) {
- /* Display currently executing ASL statement */
- next = op->common.next;
- op->common.next = NULL;
- #ifdef ACPI_DISASSEMBLER
- if (walk_state->method_node !=
- acpi_gbl_root_node) {
- /* More verbose if not module-level code */
- acpi_os_printf("Failed at ");
- acpi_dm_disassemble(next_walk_state, op,
- ACPI_UINT32_MAX);
- }
- #endif
- op->common.next = next;
- }
- } else {
- /*
- * This method has called another method
- * NOTE: the method call parse subtree is already deleted at
- * this point, so we cannot disassemble the method invocation.
- */
- ACPI_DEBUG_PRINT_RAW((ACPI_DB_DISPATCH,
- "Call to method "));
- acpi_ds_print_node_pathname(previous_method, NULL);
- }
- previous_method = next_walk_state->method_node;
- next_walk_state = next_walk_state->next;
- ACPI_DEBUG_PRINT_RAW((ACPI_DB_DISPATCH, "\n"));
- }
- return_VOID;
- }
- #else
- void
- acpi_ds_dump_method_stack(acpi_status status,
- struct acpi_walk_state *walk_state,
- union acpi_parse_object *op)
- {
- return;
- }
- #endif
|