Skip to content

Commit c91773d

Browse files
authored
Fix a multiple-definition linker error in the native API. (#1557)
* Fix a multiple-definition linker error in the native API. Remove unnecessary API implementation functions. Fix warnings.
1 parent 6893889 commit c91773d

File tree

4 files changed

+163
-172
lines changed

4 files changed

+163
-172
lines changed
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
APP_ABI := armeabi armeabi-v7a arm64-v8a x86 x86_64
1+
APP_ABI := armeabi-v7a arm64-v8a x86 x86_64
22
APP_STL := c++_static
33
NDK_TOOLCHAIN_VERSION=4.9

firebase-crashlytics-ndk/src/main/jni/libcrashlytics/include/crashlytics/external/crashlytics.h

Lines changed: 154 additions & 163 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
#include <cstddef>
1818
#include <string>
19+
#include <memory>
20+
#include <functional>
1921
#include <dlfcn.h>
2022

2123
/// @brief Firebase Crashlytics NDK API, for Android apps which use native code.
@@ -25,141 +27,134 @@
2527
/// for information on using Firebase Crashlytics in your NDK-enabled Android apps.
2628
namespace firebase { namespace crashlytics {
2729

28-
/** PUBLIC API **/
30+
/** PUBLIC API **/
2931

30-
/// @brief Initialize the Crashlytics NDK API, for Android apps using native code.
31-
///
32-
/// This must be called prior to calling any other methods in the firebase:crashlytics
33-
/// namespace. This call is only required for adding custom metadata to crash reports. Use of
34-
/// this header file is NOT required for Android NDK crash reporting.
35-
inline void Initialize();
32+
/// @brief Initialize the Crashlytics NDK API, for Android apps using native code.
33+
///
34+
/// This allows finer grained control of when the native API is initialized. Calling this
35+
/// function is not not strictly necessary as the API will be initialized on the first call
36+
/// to any of the functions within the firebase::crashlytics namespace.
37+
///
38+
/// This call is only required for adding custom metadata to crash reports. Use of
39+
/// this header file is NOT required for Android NDK crash reporting.
40+
inline bool Initialize();
3641

37-
/// @brief Terminate the Crashlytics NDK API.
38-
///
39-
/// Cleans up resources associated with the API. Subsequent calls to the Crashlytics native API
40-
/// will have no effect.
41-
inline void Terminate();
42+
/// Deprecated; now a no-op and does not need to be called.
43+
inline void Terminate();
4244

43-
/// @brief Logs a message to be included in the next fatal or non-fatal report.
44-
inline void Log(const char* msg);
45+
/// @brief Logs a message to be included in the next fatal or non-fatal report.
46+
inline void Log(const char* msg);
4547

46-
/// @brief Records a custom key and value to be associated with subsequent fatal and non-fatal
47-
/// reports.
48-
inline void SetCustomKey(const char* key, bool value);
48+
/// @brief Records a custom key and value to be associated with subsequent fatal and non-fatal
49+
/// reports.
50+
inline void SetCustomKey(const char* key, bool value);
4951

50-
/// @brief Records a custom key and value to be associated with subsequent fatal and non-fatal
51-
/// reports.
52-
inline void SetCustomKey(const char* key, const char *value);
52+
/// @brief Records a custom key and value to be associated with subsequent fatal and non-fatal
53+
/// reports.
54+
inline void SetCustomKey(const char* key, const char *value);
5355

54-
/// @brief Records a custom key and value to be associated with subsequent fatal and non-fatal
55-
/// reports.
56-
inline void SetCustomKey(const char* key, double value);
56+
/// @brief Records a custom key and value to be associated with subsequent fatal and non-fatal
57+
/// reports.
58+
inline void SetCustomKey(const char* key, double value);
5759

58-
/// @brief Records a custom key and value to be associated with subsequent fatal and non-fatal
59-
/// reports.
60-
inline void SetCustomKey(const char* key, float value);
60+
/// @brief Records a custom key and value to be associated with subsequent fatal and non-fatal
61+
/// reports.
62+
inline void SetCustomKey(const char* key, float value);
6163

62-
/// @brief Records a custom key and value to be associated with subsequent fatal and non-fatal
63-
/// reports.
64-
inline void SetCustomKey(const char* key, int value);
64+
/// @brief Records a custom key and value to be associated with subsequent fatal and non-fatal
65+
/// reports.
66+
inline void SetCustomKey(const char* key, int value);
6567

66-
/// @brief Records a custom key and value to be associated with subsequent fatal and non-fatal
67-
/// reports.
68-
inline void SetCustomKey(const char* key, long value);
68+
/// @brief Records a custom key and value to be associated with subsequent fatal and non-fatal
69+
/// reports.
70+
inline void SetCustomKey(const char* key, long value);
6971

70-
/// @brief Records a user ID (identifier) that's associated with subsequent fatal and non-fatal
71-
/// reports.
72-
inline void SetUserId(const char* id);
72+
/// @brief Records a user ID (identifier) that's associated with subsequent fatal and non-fatal
73+
/// reports.
74+
inline void SetUserId(const char* id);
7375

74-
/** END PUBLIC API **/
76+
/** END PUBLIC API **/
7577

76-
struct __crashlytics_context;
77-
struct __crashlytics_unspecified;
78-
typedef struct __crashlytics_context __crashlytics_context_t;
79-
typedef struct __crashlytics_unspecified __crashlytics_unspecified_t;
78+
namespace detail {
8079

81-
typedef __crashlytics_unspecified_t* (*__crashlytics_initialize_t) ();
82-
typedef void (*__crashlytics_set_internal_t) (__crashlytics_unspecified_t *, const char *, const char *);
83-
typedef void (*__crashlytics_log_internal_t) (__crashlytics_unspecified_t *, const char *);
84-
typedef void (*__crashlytics_set_user_id_internal_t)(__crashlytics_unspecified_t *, const char *);
85-
typedef void (*__crashlytics_dispose_t) (__crashlytics_unspecified_t *);
80+
struct __crashlytics_context;
81+
struct __crashlytics_unspecified;
82+
typedef struct __crashlytics_context __crashlytics_context_t;
83+
typedef struct __crashlytics_unspecified __crashlytics_unspecified_t;
8684

87-
struct __crashlytics_context {
85+
typedef __crashlytics_unspecified_t* (*__crashlytics_initialize_t) ();
86+
typedef void (*__crashlytics_set_internal_t) (__crashlytics_unspecified_t *, const char *, const char *);
87+
typedef void (*__crashlytics_log_internal_t) (__crashlytics_unspecified_t *, const char *);
88+
typedef void (*__crashlytics_set_user_id_internal_t) (__crashlytics_unspecified_t *, const char *);
89+
typedef void (*__crashlytics_dispose_t) (__crashlytics_unspecified_t *);
8890

89-
__crashlytics_set_internal_t __set;
90-
__crashlytics_log_internal_t __log;
91-
__crashlytics_set_user_id_internal_t __set_user_id;
91+
struct __crashlytics_context {
92+
__crashlytics_set_internal_t __set;
93+
__crashlytics_log_internal_t __log;
94+
__crashlytics_set_user_id_internal_t __set_user_id;
9295

93-
__crashlytics_unspecified_t* __ctx;
94-
__crashlytics_dispose_t __dispose;
95-
};
96+
__crashlytics_unspecified_t* __ctx;
97+
__crashlytics_dispose_t __dispose;
98+
};
9699

97100
#define __CRASHLYTICS_NULL_CONTEXT (struct __crashlytics_context *) 0
98101
#define __CRASHLYTICS_INITIALIZE_FAILURE (struct __crashlytics_unspecified *) 0
99102
#define __CRASHLYTICS_DECORATED __attribute__ ((always_inline))
100103

104+
inline const __crashlytics_context_t* __crashlytics_context() __CRASHLYTICS_DECORATED;
105+
inline __crashlytics_context_t* __crashlytics_init() __CRASHLYTICS_DECORATED;
101106

102-
static inline __crashlytics_context_t* __crashlytics_init() __CRASHLYTICS_DECORATED;
103-
static inline void __crashlytics_free(__crashlytics_context_t** context) __CRASHLYTICS_DECORATED;
107+
inline void invoke(const std::function<void (const __crashlytics_context_t *)>& func) __CRASHLYTICS_DECORATED;
104108

105-
__crashlytics_context_t* __context;
109+
} // end namespace detail
106110

107-
inline bool VerifyCrashlytics() {
108-
if (__context) {
109-
return true;
110-
}
111-
return false;
112-
}
111+
inline bool Initialize() {
112+
return detail::__crashlytics_context() != nullptr;
113+
}
113114

114-
inline void Initialize() {
115-
__context = __crashlytics_init();
116-
VerifyCrashlytics();
117-
}
115+
inline void Terminate() {
116+
// no-op
117+
}
118118

119-
inline void Terminate() {
120-
if (VerifyCrashlytics()) {
121-
__crashlytics_free(&__context);
122-
}
123-
}
124-
125-
inline void Log(const char* msg) {
126-
if (VerifyCrashlytics()) {
127-
__context->__log(__context->__ctx, msg);
128-
}
129-
}
119+
inline void Log(const char* msg) {
120+
detail::invoke([&](const detail::__crashlytics_context_t* context) {
121+
context->__log(context->__ctx, msg);
122+
});
123+
}
130124

131-
inline void SetCustomKey(const char* key, const char* value) {
132-
if (VerifyCrashlytics()) {
133-
__context->__set(__context->__ctx, key, value);
134-
}
135-
}
125+
inline void SetCustomKey(const char* key, const char* value) {
126+
detail::invoke([&](const detail::__crashlytics_context_t* context) {
127+
context->__set(context->__ctx, key, value);
128+
});
129+
}
136130

137-
inline void SetCustomKey(const char* key, bool value) {
138-
SetCustomKey(key, value ? "true" : "false");
139-
}
131+
inline void SetCustomKey(const char* key, bool value) {
132+
SetCustomKey(key, value ? "true" : "false");
133+
}
140134

141-
inline void SetCustomKey(const char* key, double value) {
142-
SetCustomKey(key, std::to_string(value).c_str());
143-
}
135+
inline void SetCustomKey(const char* key, double value) {
136+
SetCustomKey(key, std::to_string(value).c_str());
137+
}
144138

145-
inline void SetCustomKey(const char* key, float value) {
146-
SetCustomKey(key, std::to_string(value).c_str());
147-
}
139+
inline void SetCustomKey(const char* key, float value) {
140+
SetCustomKey(key, std::to_string(value).c_str());
141+
}
148142

149-
inline void SetCustomKey(const char* key, int value) {
150-
SetCustomKey(key, std::to_string(value).c_str());
151-
}
143+
inline void SetCustomKey(const char* key, int value) {
144+
SetCustomKey(key, std::to_string(value).c_str());
145+
}
152146

153-
inline void SetCustomKey(const char* key, long value) {
154-
SetCustomKey(key, std::to_string(value).c_str());
155-
}
147+
inline void SetCustomKey(const char* key, long value) {
148+
SetCustomKey(key, std::to_string(value).c_str());
149+
}
156150

157-
inline void SetUserId(const char* id) {
158-
if (VerifyCrashlytics()) {
159-
__context->__set_user_id(__context->__ctx, id);
160-
}
161-
}
151+
inline void SetUserId(const char* id) {
152+
detail::invoke([&](const detail::__crashlytics_context_t* context) {
153+
context->__set_user_id(context->__ctx, id);
154+
});
155+
}
162156

157+
namespace detail {
163158

164159
#define __CRASHLYTICS_NULL_ON_NULL(expression) \
165160
do { \
@@ -168,69 +163,65 @@ namespace firebase { namespace crashlytics {
168163
} \
169164
} while (0)
170165

171-
static inline __crashlytics_context_t* __crashlytics_allocate() __CRASHLYTICS_DECORATED;
172-
static inline __crashlytics_context_t* __crashlytics_allocate() {
173-
return new __crashlytics_context_t;
174-
}
175-
176-
static inline __crashlytics_context_t* __crashlytics_construct(
177-
__crashlytics_unspecified_t* ctx, void* sym_set, void* sym_log, void* sym_dispose, void* sym_set_user_id) __CRASHLYTICS_DECORATED;
178-
static inline __crashlytics_context_t* __crashlytics_construct(
179-
__crashlytics_unspecified_t* ctx, void* sym_set, void* sym_log, void* sym_dispose, void* sym_set_user_id) {
180-
__crashlytics_context_t* context;
181-
182-
__CRASHLYTICS_NULL_ON_NULL(context = __crashlytics_allocate());
183-
184-
context->__set = (__crashlytics_set_internal_t) sym_set;
185-
context->__log = (__crashlytics_log_internal_t) sym_log;
186-
context->__set_user_id = (__crashlytics_set_user_id_internal_t) sym_set_user_id;
187-
context->__ctx = ctx;
188-
context->__dispose = (__crashlytics_dispose_t) sym_dispose;
166+
inline __crashlytics_context_t* __crashlytics_construct(
167+
__crashlytics_unspecified_t* ctx, void* sym_set, void* sym_log, void* sym_dispose, void* sym_set_user_id) __CRASHLYTICS_DECORATED;
168+
inline __crashlytics_context_t* __crashlytics_construct(
169+
__crashlytics_unspecified_t* ctx, void* sym_set, void* sym_log, void* sym_dispose, void* sym_set_user_id) {
170+
__crashlytics_context_t* context;
171+
172+
__CRASHLYTICS_NULL_ON_NULL(context = new __crashlytics_context_t);
173+
174+
context->__set = (__crashlytics_set_internal_t) sym_set;
175+
context->__log = (__crashlytics_log_internal_t) sym_log;
176+
context->__set_user_id = (__crashlytics_set_user_id_internal_t) sym_set_user_id;
177+
context->__ctx = ctx;
178+
context->__dispose = (__crashlytics_dispose_t) sym_dispose;
179+
180+
return context;
181+
}
182+
183+
inline const __crashlytics_context_t* __crashlytics_context() {
184+
static std::unique_ptr<__crashlytics_context_t> context { __crashlytics_init() };
185+
return context.get();
186+
}
187+
188+
inline __crashlytics_context_t* __crashlytics_init() {
189+
void* lib;
190+
void* sym_ini;
191+
void* sym_log;
192+
void* sym_set;
193+
void* sym_dispose;
194+
void* sym_set_user_id;
195+
196+
__CRASHLYTICS_NULL_ON_NULL(lib = dlopen("libcrashlytics.so", RTLD_LAZY | RTLD_LOCAL));
197+
__CRASHLYTICS_NULL_ON_NULL(sym_ini = dlsym(lib, "external_api_initialize"));
198+
__CRASHLYTICS_NULL_ON_NULL(sym_set = dlsym(lib, "external_api_set"));
199+
__CRASHLYTICS_NULL_ON_NULL(sym_log = dlsym(lib, "external_api_log"));
200+
__CRASHLYTICS_NULL_ON_NULL(sym_dispose = dlsym(lib, "external_api_dispose"));
201+
__CRASHLYTICS_NULL_ON_NULL(sym_set_user_id = dlsym(lib, "external_api_set_user_id"));
202+
203+
__crashlytics_unspecified_t* ctx = ((__crashlytics_initialize_t) sym_ini)();
204+
205+
return ctx == __CRASHLYTICS_INITIALIZE_FAILURE
206+
? __CRASHLYTICS_NULL_CONTEXT
207+
: __crashlytics_construct(
208+
ctx,
209+
sym_set,
210+
sym_log,
211+
sym_dispose,
212+
sym_set_user_id
213+
);
214+
}
215+
216+
inline void invoke(const std::function<void (const __crashlytics_context_t *)>& func) {
217+
const __crashlytics_context_t* context = __crashlytics_context();
218+
if (context != nullptr) {
219+
func(context);
220+
}
221+
}
222+
223+
} // end namespace detail
189224

190-
return context;
191-
}
192-
193-
static inline __crashlytics_context_t* __crashlytics_init() {
194-
void* lib;
195-
void* sym_ini;
196-
void* sym_log;
197-
void* sym_set;
198-
void* sym_dispose;
199-
void* sym_set_user_id;
200-
201-
__CRASHLYTICS_NULL_ON_NULL(lib = dlopen("libcrashlytics.so", RTLD_LAZY | RTLD_LOCAL));
202-
__CRASHLYTICS_NULL_ON_NULL(sym_ini = dlsym(lib, "external_api_initialize"));
203-
__CRASHLYTICS_NULL_ON_NULL(sym_set = dlsym(lib, "external_api_set"));
204-
__CRASHLYTICS_NULL_ON_NULL(sym_log = dlsym(lib, "external_api_log"));
205-
__CRASHLYTICS_NULL_ON_NULL(sym_dispose = dlsym(lib, "external_api_dispose"));
206-
__CRASHLYTICS_NULL_ON_NULL(sym_set_user_id = dlsym(lib, "external_api_set_user_id"));
207-
208-
__crashlytics_unspecified_t* ctx = ((__crashlytics_initialize_t) sym_ini)();
209-
210-
return ctx == __CRASHLYTICS_INITIALIZE_FAILURE ? __CRASHLYTICS_NULL_CONTEXT
211-
: __crashlytics_construct(
212-
ctx,
213-
sym_set,
214-
sym_log,
215-
sym_dispose,
216-
sym_set_user_id
217-
);
218-
}
219-
220-
static inline void __crashlytics_deallocate(__crashlytics_context_t* context) __CRASHLYTICS_DECORATED;
221-
static inline void __crashlytics_deallocate(__crashlytics_context_t* context) {
222-
delete context;
223-
}
224-
225-
static inline void __crashlytics_free(__crashlytics_context_t** context) {
226-
if ((*context) != __CRASHLYTICS_NULL_CONTEXT) {
227-
(*context)->__dispose((*context)->__ctx);
228-
229-
__crashlytics_deallocate(*context);
230-
231-
(*context) = __CRASHLYTICS_NULL_CONTEXT;
232-
}
233-
}
234225
}} // end namespace firebase::crashlytics
235226

236227
#endif /* __CRASHLYTICS_H__ */

firebase-crashlytics-ndk/src/main/jni/libcrashlytics/include/crashlytics/handler/maps.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,8 @@ template<typename Storage> struct maps {
5656
typedef typename Storage::value_type entry_type;
5757
typedef typename Storage::size_type size_type;
5858

59-
constexpr size_type upper_bound() { return std::tuple_size<Storage>::value; }
60-
constexpr size_type entry_bound() { return maps_entry_length<entry_type>::value; }
59+
constexpr size_type upper_bound() const { return std::tuple_size<Storage>::value; }
60+
constexpr size_type entry_bound() const { return maps_entry_length<entry_type>::value; }
6161

6262
maps() : count(0) {}
6363
~maps() {}

0 commit comments

Comments
 (0)