2 * Copyright 2013 Facebook, Inc.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 #include "folly/experimental/exception_tracer/StackTrace.h"
30 static _Unwind_Reason_Code addIP(struct _Unwind_Context* ctx, void* varg) {
31 struct Context* arg = (struct Context*)varg;
35 return _URC_NO_REASON;
38 if (arg->trace->frameCount == arg->capacity) {
39 size_t newCapacity = (arg->capacity < 8 ? 8 : arg->capacity * 1.5);
41 realloc(arg->trace->frameIPs, newCapacity * sizeof(uintptr_t));
43 return _URC_FATAL_PHASE1_ERROR;
45 arg->trace->frameIPs = newBlock;
46 arg->capacity = newCapacity;
49 arg->trace->frameIPs[arg->trace->frameCount++] = _Unwind_GetIP(ctx);
50 return _URC_NO_REASON; /* success */
53 int getCurrentStackTrace(size_t skip, StackTrace* trace) {
54 trace->frameIPs = NULL;
55 trace->frameCount = 0;
61 if (_Unwind_Backtrace(addIP, &ctx) == _URC_END_OF_STACK) {
65 destroyStackTrace(trace);
69 void destroyStackTrace(StackTrace* trace) {
70 free(trace->frameIPs);
71 trace->frameIPs = NULL;
72 trace->frameCount = 0;
75 int pushCurrentStackTrace(size_t skip, StackTraceStack** head) {
76 StackTraceStack* newHead = malloc(sizeof(StackTraceStack));
82 if ((err = getCurrentStackTrace(skip, &newHead->trace)) != 0) {
87 newHead->next = *head;
92 void popStackTrace(StackTraceStack** head) {
93 StackTraceStack* oldHead = *head;
94 *head = oldHead->next;
95 destroyStackTrace(&oldHead->trace);
99 void clearStack(StackTraceStack** head) {
105 int moveTop(StackTraceStack** from, StackTraceStack** to) {
106 StackTraceStack* top = *from;