2 * Copyright (c) 2023 Samsung Electronics Co., Ltd.
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.
19 #include <dali/public-api/common/dali-common.h>
26 #if defined(BACKTRACE_ENABLED)
27 #if defined(__GLIBC__)
35 #include <dali/integration-api/debug.h>
39 #if defined(BACKTRACE_ENABLED)
43 const int32_t MAX_NUM_STACK_FRAMES = 25;
46 std::string Demangle(const char* symbol)
50 // backtrace ::= <filename>'('['_'<mangled-symbol>'_']['+'<offset>]')'
51 // Only want <mangled-symbol>:
52 const char* openParen = strchr(symbol, '(');
55 const char* startOfToken = openParen + 1;
56 const char* plus = strchr(startOfToken, '+');
57 const char* closeParen = strchr(startOfToken, ')');
58 const char* endOfToken = NULL;
63 else if(closeParen != NULL)
65 endOfToken = closeParen;
67 if(endOfToken != NULL)
69 size_t tokenLength = endOfToken - startOfToken;
71 // Allocate space for symbol
72 char* mangledSymbol = reinterpret_cast<char*>(malloc(tokenLength + 1u));
73 if(mangledSymbol != NULL)
75 strncpy(mangledSymbol, startOfToken, tokenLength);
76 mangledSymbol[tokenLength] = '\0';
80 char* demangled = NULL;
81 demangled = abi::__cxa_demangle(mangledSymbol, NULL, &size, &status);
85 free(demangled); // demangle() allocates returned string, so free it
99 DALI_CORE_API DaliException::DaliException(const char* location, const char* condition)
100 : location(location),
103 // Note, if a memory error has occured, then the backtrace won't work - backtrace_symbols relies on
104 // allocating memory.
106 // Initial dlog error message is output in DALI_ASSERT_ALWAYS macro
107 // Also output on stderr
108 #if defined(DEBUG_ENABLED)
109 fprintf(stderr, "Exception: \n%s\n thrown at %s\nSee dlog for backtrace\n", condition, location);
111 fprintf(stderr, "Exception: \n%s\n thrown\nSee dlog for backtrace\n", condition);
114 DALI_LOG_ERROR_NOFN("Backtrace:\n");
116 void* frameArray[MAX_NUM_STACK_FRAMES];
117 int32_t nSize = backtrace(frameArray, MAX_NUM_STACK_FRAMES);
118 char** symbols = backtrace_symbols(frameArray, nSize);
119 for(int32_t i = 1; i < nSize; i++)
121 std::string demangled_symbol = Demangle(symbols[i]);
122 DALI_LOG_ERROR_NOFN("[%02d] %s\n", i, demangled_symbol.c_str());
127 DALI_CORE_API void DaliPrintBackTrace()
129 DALI_LOG_ERROR_NOFN("Backtrace:\n");
131 void* frameArray[MAX_NUM_STACK_FRAMES];
132 int32_t nSize = backtrace(frameArray, MAX_NUM_STACK_FRAMES);
133 char** symbols = backtrace_symbols(frameArray, nSize);
134 for(int32_t i = 1; i < nSize; i++)
136 std::string demangled_symbol = Demangle(symbols[i]);
137 DALI_LOG_ERROR_NOFN("[%02d] %s\n", i, demangled_symbol.c_str());
142 #else // BACKTRACE_ENABLED
144 DALI_CORE_API DaliException::DaliException(const char* location, const char* condition)
145 : location(location),
148 #if defined(DEBUG_ENABLED)
149 printf("Exception: \n%s\n thrown at %s\n", condition, location);
151 printf("Exception: \n%s\n thrown\n", condition);
155 DALI_CORE_API void DaliPrintBackTrace()
159 #endif // BACKTRACE_ENABLED
161 DALI_CORE_API void DaliAssertMessage(const char* location, const char* condition)
163 #if defined(DEBUG_ENABLED)
164 DALI_LOG_ERROR_NOFN("Assert (%s) failed in: %s\n", condition, location);
166 DALI_LOG_ERROR_NOFN("Assert (%s) failed\n", condition);