source: mainline/kernel/generic/src/debug/stacktrace.c@ 001957b6

topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 001957b6 was 001957b6, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 20 months ago

ccheck

  • Property mode set to 100644
File size: 4.2 KB
Line 
1/*
2 * Copyright (c) 2009 Jakub Jermar
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup kernel_generic_debug
30 * @{
31 */
32/** @file
33 */
34
35#include <stacktrace.h>
36#include <stdbool.h>
37#include <interrupt.h>
38#include <symtab.h>
39#include <stdio.h>
40
41#include <debug/line.h>
42
43#define STACK_FRAMES_MAX 20
44
45void stack_trace_ctx(stack_trace_ops_t *ops, stack_trace_context_t *ctx)
46{
47 int cnt = 0;
48
49 uintptr_t fp;
50 uintptr_t pc;
51
52 while ((cnt++ < STACK_FRAMES_MAX) &&
53 (ops->stack_trace_context_validate(ctx))) {
54
55 const char *symbol = NULL;
56 uintptr_t symbol_addr = 0;
57 const char *file_name = NULL;
58 const char *dir_name = NULL;
59 int line = 0;
60 int column = 0;
61
62 if (ops->symbol_resolve &&
63 ops->symbol_resolve(ctx->pc, 0, &symbol, &symbol_addr, &file_name, &dir_name, &line, &column)) {
64
65 if (symbol == NULL)
66 symbol = "<unknown>";
67
68 if (file_name == NULL && line == 0) {
69 printf("%p: %24s()+%zu\n", (void *) ctx->fp, symbol, ctx->pc - symbol_addr);
70 } else {
71 if (file_name == NULL)
72 file_name = "<unknown>";
73 if (dir_name == NULL)
74 dir_name = "<unknown>";
75
76 printf("%p: %20s()+%zu\t %s/%s:%d:%d\n",
77 (void *) ctx->fp, symbol, ctx->pc - symbol_addr,
78 dir_name, file_name, line, column);
79 }
80 } else
81 printf("%p: %p()\n", (void *) ctx->fp, (void *) ctx->pc);
82
83 if (!ops->return_address_get(ctx, &pc))
84 break;
85
86 if (!ops->frame_pointer_prev(ctx, &fp))
87 break;
88
89 ctx->fp = fp;
90 ctx->pc = pc;
91 }
92}
93
94void stack_trace(void)
95{
96 stack_trace_context_t ctx = {
97 .fp = frame_pointer_get(),
98 .pc = program_counter_get(),
99 .istate = NULL
100 };
101
102 stack_trace_ctx(&kst_ops, &ctx);
103
104 /*
105 * Prevent the tail call optimization of the previous call by
106 * making it a non-tail call.
107 */
108 (void) frame_pointer_get();
109}
110
111void stack_trace_istate(istate_t *istate)
112{
113 stack_trace_context_t ctx = {
114 .fp = istate_get_fp(istate),
115 .pc = istate_get_pc(istate),
116 .istate = istate
117 };
118
119 if (istate_from_uspace(istate))
120 stack_trace_ctx(&ust_ops, &ctx);
121 else
122 stack_trace_ctx(&kst_ops, &ctx);
123}
124
125static bool
126resolve_kernel_address(uintptr_t addr, int op_index,
127 const char **symbol, uintptr_t *symbol_addr,
128 const char **filename, const char **dirname,
129 int *line, int *column)
130{
131 *symbol_addr = 0;
132 *symbol = symtab_name_lookup(addr, symbol_addr);
133
134 return debug_line_get_address_info(addr, op_index, filename, dirname, line, column) || *symbol_addr != 0;
135}
136
137stack_trace_ops_t kst_ops = {
138 .stack_trace_context_validate = kernel_stack_trace_context_validate,
139 .frame_pointer_prev = kernel_frame_pointer_prev,
140 .return_address_get = kernel_return_address_get,
141 .symbol_resolve = resolve_kernel_address,
142};
143
144stack_trace_ops_t ust_ops = {
145 .stack_trace_context_validate = uspace_stack_trace_context_validate,
146 .frame_pointer_prev = uspace_frame_pointer_prev,
147 .return_address_get = uspace_return_address_get,
148 .symbol_resolve = NULL
149};
150
151/** @}
152 */
Note: See TracBrowser for help on using the repository browser.