tizen 2.3.1 release
[framework/system/sys-assert.git] / src / x86 / backtrace.c
1 /*
2  * SYS-ASSERT
3  * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
4  *
5  * Licensed under the Apache License, Version 2.0 (the License);
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 #define _GNU_SOURCE
18 #include <stdlib.h>
19 #include <stdio.h>
20 #include <execinfo.h>
21 #include <ucontext.h>
22 #include "sys-assert.h"
23 #include "util.h"
24
25 int dump_callstack(void **callstack_addrs, int size, void *context, int retry)
26 {
27         ucontext_t *ucontext = context;
28         int count = CALLSTACK_BASE;
29
30         if (!callstack_addrs)
31                 return 0;
32
33         if (context) {
34                 layout *ebp = (layout *)ucontext->uc_mcontext.gregs[REG_EBP];
35                 callstack_addrs[count++] =
36                         (long *)ucontext->uc_mcontext.gregs[REG_EIP];
37                 while (ebp && (count < size)) {
38                         callstack_addrs[count++] = ebp->ret;
39                         ebp = ebp->ebp;
40                 }
41         } else {
42                 count = backtrace(callstack_addrs, size);
43         }
44
45         if (count > CALLSTACK_BASE) {
46                 count -= CALLSTACK_BASE;
47         } else if (context) {
48                 callstack_addrs[CALLSTACK_BASE] = (long *)ucontext->uc_mcontext.gregs[REG_EIP];
49                 callstack_addrs[CALLSTACK_BASE + 1] = (long *)ucontext->uc_mcontext.gregs[REG_ESP];
50                 count = 2;
51         } else {
52                 count = 0;
53         }
54         return count;
55 };