Update copyright year to 2015 for public api: core
[platform/core/uifw/dali-core.git] / dali / public-api / common / dali-common.cpp
1 /*
2  * Copyright (c) 2015 Samsung Electronics Co., Ltd.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  *
16  */
17
18 // CLASS HEADER
19 #include <dali/public-api/common/dali-common.h>
20
21 // EXTERNAL INCLUDES
22 #include <stdlib.h>
23 #include <string>
24 #include <cstdio>
25
26 #ifndef EMSCRIPTEN // cxxabi not supported
27 # include <execinfo.h>
28 # include <cxxabi.h>
29 #endif
30
31 #include <cstring>
32
33 // INTERNAL INCLUDES
34 #include <dali/integration-api/debug.h>
35
36 namespace
37 {
38 const int MAX_NUM_STACK_FRAMES = 25;
39 }
40
41 namespace Dali
42 {
43
44 #if defined(BACKTRACE_ENABLED)
45
46 std::string Demangle(const char* symbol)
47 {
48   std::string result;
49
50   // backtrace ::=  <filename>'('['_'<mangled-symbol>'_']['+'<offset>]')'
51   // Only want <mangled-symbol>:
52   const char* openParen = strchr(symbol, '(');
53   if(openParen != NULL)
54   {
55     const char* startOfToken = openParen + 1;
56     const char* plus = strchr(startOfToken, '+');
57     const char* closeParen = strchr(startOfToken, ')');
58     const char* endOfToken = NULL;
59     if(plus != NULL)
60     {
61       endOfToken = plus;
62     }
63     else if(closeParen != NULL)
64     {
65       endOfToken = closeParen;
66     }
67     if(endOfToken != NULL)
68     {
69       size_t tokenLength = endOfToken - startOfToken;
70
71       // Allocate space for symbol
72       char *mangledSymbol = (char*)malloc(tokenLength+1u);
73       if(mangledSymbol != NULL)
74       {
75         strncpy(mangledSymbol, startOfToken, tokenLength);
76         mangledSymbol[tokenLength] = '\0';
77
78         size_t size;
79         int    status;
80         char*  demangled=NULL;
81         demangled = abi::__cxa_demangle( mangledSymbol, NULL, &size, &status );
82         if( demangled != NULL )
83         {
84           result = demangled;
85           free(demangled); // demangle() allocates returned string, so free it
86         }
87         else
88         {
89           result = symbol;
90         }
91         free(mangledSymbol);
92       }
93     }
94   }
95
96   return result;
97 }
98
99 DALI_EXPORT_API DaliException::DaliException( const char* location, const char* condition )
100 : location( location ), condition( condition )
101 {
102   // Note, if a memory error has occured, then the backtrace won't work - backtrace_symbols relies on
103   // allocating memory.
104
105   // Initial dlog error message is output in DALI_ASSERT_ALWAYS macro
106   // Also output on stderr
107 #if defined(DEBUG_ENABLED)
108   fprintf(stderr, "Exception: \n%s\n thrown at %s\nSee dlog for backtrace\n", condition, location);
109 #else
110   fprintf(stderr, "Exception: \n%s\n thrown\nSee dlog for backtrace\n", condition );
111 #endif
112
113   DALI_LOG_ERROR_NOFN("Backtrace:\n");
114
115   void* frameArray[MAX_NUM_STACK_FRAMES];
116   int nSize = backtrace(frameArray, MAX_NUM_STACK_FRAMES);
117   char** symbols = backtrace_symbols(frameArray, nSize);
118   for(int i=1; i< nSize; i++)
119   {
120     std::string demangled_symbol = Demangle(symbols[i]);
121     DALI_LOG_ERROR_NOFN("[%02d]   %s\n", i, demangled_symbol.c_str() );
122   }
123   free(symbols);
124 }
125
126
127 #else // BACKTRACE_ENABLED
128
129 DALI_EXPORT_API DaliException::DaliException( const char* location, const char* condition )
130 : location( location ), condition( condition )
131 {
132 #if defined(DEBUG_ENABLED)
133   printf("Exception: \n%s\n thrown at %s\n", condition, location );
134 #else
135   printf("Exception: \n%s\n thrown\n", condition );
136 #endif
137 }
138
139
140 #endif // BACKTRACE_ENABLED
141
142 DALI_EXPORT_API void DaliAssertMessage( const char* location, const char* condition )
143 {
144 #if defined(DEBUG_ENABLED)
145   DALI_LOG_ERROR_NOFN( "Assert (%s) failed in: %s\n", condition, location );
146 #else
147   DALI_LOG_ERROR_NOFN( "Assert (%s) failed\n", condition );
148 #endif
149 }
150
151 } // Dali