Skip to content

Commit 0f73dd2

Browse files
committed
BUG: Fixes crashing issues on macOS Xcode 16 in debug mode.
The bug is from some change in Xcode 16.x where using inline const std::string was causing cross translation unit initialization crashes (seg-fault). Signed-off-by: Michael Jackson <mike.jackson@bluequartz.net>BUG
1 parent d14bf1a commit 0f73dd2

File tree

5 files changed

+97
-63
lines changed

5 files changed

+97
-63
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ set(CMAKE_CXX_EXTENSIONS OFF)
1515
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
1616

1717
# set project's name
18-
project(EbsdLibProj VERSION 1.0.35)
18+
project(EbsdLibProj VERSION 1.0.36)
1919

2020
# ---------- Setup output Directories -------------------------
2121
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY

Source/EbsdLib/Core/EbsdLibConstants.h

Lines changed: 50 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,25 @@
3333
*
3434
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
3535

36+
/** !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
37+
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
38+
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
39+
* =======================> MAC OS WARNING <================================
40+
* Xcode 16 has changes specific to Apple systems where using a static const std::string variable
41+
* inside of an inline function in this header will lead to executable crashes
42+
* in Debug (but not release). This is why the use of StringLiteral was introduced.
43+
*
44+
* EbsdStringLiteral are stack allocated instead of heap allocated. Which is Good.
45+
*
46+
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
47+
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
48+
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
49+
*/
3650
#pragma once
3751

52+
#include "EbsdLib/Core/EbsdStringLiteral.hpp"
53+
#include "EbsdLib/EbsdLib.h"
54+
3855
#include <cstdint>
3956
#include <string>
4057

@@ -47,7 +64,7 @@ namespace EbsdLib
4764

4865
using Rgb = uint32_t;
4966
inline constexpr Rgb RGB_MASK = 0x00ffffff; // masks RGB values
50-
inline const std::string PathSep("|");
67+
EbsdLib_macOS_NO_EXPORT inline constexpr EbsdStringLiteral PathSep("|");
5168
inline constexpr uint8_t Unchecked = 0;
5269
inline constexpr uint8_t PartiallyChecked = 1;
5370
inline constexpr uint8_t Checked = 2;
@@ -64,10 +81,10 @@ enum InfoStringFormat
6481

6582
namespace StringConstants
6683
{
67-
inline const std::string Statistics("Statistics");
68-
inline const std::string StatsData("StatsData");
69-
inline const std::string StatsType("StatsType");
70-
inline const std::string GBCD("GBCD");
84+
EbsdLib_macOS_NO_EXPORT inline constexpr EbsdStringLiteral Statistics("Statistics");
85+
EbsdLib_macOS_NO_EXPORT inline constexpr EbsdStringLiteral StatsData("StatsData");
86+
EbsdLib_macOS_NO_EXPORT inline constexpr EbsdStringLiteral StatsType("StatsType");
87+
EbsdLib_macOS_NO_EXPORT inline constexpr EbsdStringLiteral GBCD("GBCD");
7188
} // namespace StringConstants
7289

7390
namespace NumericTypes
@@ -102,35 +119,35 @@ inline constexpr uint32_t UnknownRefFrameZDirection = 2;
102119

103120
namespace H5Ebsd
104121
{
105-
inline const std::string Manufacturer("Manufacturer");
106-
inline const std::string Header("Header");
107-
inline const std::string Phases("Phases");
108-
inline const std::string Phase("Phase");
109-
inline const std::string Data("Data");
110-
inline const std::string Index("Index");
122+
EbsdLib_macOS_NO_EXPORT inline constexpr EbsdStringLiteral Manufacturer("Manufacturer");
123+
EbsdLib_macOS_NO_EXPORT inline constexpr EbsdStringLiteral Header("Header");
124+
EbsdLib_macOS_NO_EXPORT inline constexpr EbsdStringLiteral Phases("Phases");
125+
EbsdLib_macOS_NO_EXPORT inline constexpr EbsdStringLiteral Phase("Phase");
126+
EbsdLib_macOS_NO_EXPORT inline constexpr EbsdStringLiteral Data("Data");
127+
EbsdLib_macOS_NO_EXPORT inline constexpr EbsdStringLiteral Index("Index");
111128

112-
inline const std::string ZStartIndex("ZStartIndex");
113-
inline const std::string ZEndIndex("ZEndIndex");
114-
inline const std::string ZResolution("Z Resolution");
115-
inline const std::string StackingOrder("Stacking Order");
116-
inline const std::string SampleTransformationAngle("SampleTransformationAngle");
117-
inline const std::string SampleTransformationAxis("SampleTransformationAxis");
118-
inline const std::string EulerTransformationAngle("EulerTransformationAngle");
119-
inline const std::string EulerTransformationAxis("EulerTransformationAxis");
129+
EbsdLib_macOS_NO_EXPORT inline constexpr EbsdStringLiteral ZStartIndex("ZStartIndex");
130+
EbsdLib_macOS_NO_EXPORT inline constexpr EbsdStringLiteral ZEndIndex("ZEndIndex");
131+
EbsdLib_macOS_NO_EXPORT inline constexpr EbsdStringLiteral ZResolution("Z Resolution");
132+
EbsdLib_macOS_NO_EXPORT inline constexpr EbsdStringLiteral StackingOrder("Stacking Order");
133+
EbsdLib_macOS_NO_EXPORT inline constexpr EbsdStringLiteral SampleTransformationAngle("SampleTransformationAngle");
134+
EbsdLib_macOS_NO_EXPORT inline constexpr EbsdStringLiteral SampleTransformationAxis("SampleTransformationAxis");
135+
EbsdLib_macOS_NO_EXPORT inline constexpr EbsdStringLiteral EulerTransformationAngle("EulerTransformationAngle");
136+
EbsdLib_macOS_NO_EXPORT inline constexpr EbsdStringLiteral EulerTransformationAxis("EulerTransformationAxis");
120137

121138
// Each Manufacturer has their own naming scheme for these variables but for
122139
// DREAM.3D we are going to settle on using these names for consistency
123-
inline const std::string XResolution("X Resolution");
124-
inline const std::string YResolution("Y Resolution");
140+
EbsdLib_macOS_NO_EXPORT inline constexpr EbsdStringLiteral XResolution("X Resolution");
141+
EbsdLib_macOS_NO_EXPORT inline constexpr EbsdStringLiteral YResolution("Y Resolution");
125142

126143
// We store the Maximum number of X and Y Points for the given volume. This
127144
// allows us to store slices that have different XY voxel dimensions.
128-
inline const std::string XPoints("Max X Points");
129-
inline const std::string YPoints("Max Y Points");
145+
EbsdLib_macOS_NO_EXPORT inline constexpr EbsdStringLiteral XPoints("Max X Points");
146+
EbsdLib_macOS_NO_EXPORT inline constexpr EbsdStringLiteral YPoints("Max Y Points");
130147

131-
inline const std::string FileVersionStr("FileVersion");
148+
EbsdLib_macOS_NO_EXPORT inline constexpr EbsdStringLiteral FileVersionStr("FileVersion");
132149
inline constexpr uint32_t FileVersion = 5;
133-
inline const std::string EbsdLibVersionStr("EbsdLibVersion");
150+
EbsdLib_macOS_NO_EXPORT inline constexpr EbsdStringLiteral EbsdLibVersionStr("EbsdLibVersion");
134151
} // namespace H5Ebsd
135152

136153
using EnumType = int32_t;
@@ -149,8 +166,8 @@ enum class OEM : EnumType
149166

150167
namespace CellData
151168
{
152-
inline const std::string EulerAngles("EulerAngles");
153-
inline const std::string Phases("Phases");
169+
EbsdLib_macOS_NO_EXPORT inline constexpr EbsdStringLiteral EulerAngles("EulerAngles");
170+
EbsdLib_macOS_NO_EXPORT inline constexpr EbsdStringLiteral Phases("Phases");
154171
} // namespace CellData
155172

156173
enum EbsdToSampleCoordinateMapping
@@ -163,9 +180,9 @@ enum EbsdToSampleCoordinateMapping
163180

164181
namespace StackingOrder
165182
{
166-
inline const std::string LowToHigh("Low To High");
167-
inline const std::string HighToLow("High To Low");
168-
inline const std::string UnknownStackingOrder("Unknown Stacking Order");
183+
EbsdLib_macOS_NO_EXPORT inline constexpr EbsdStringLiteral LowToHigh("Low To High");
184+
EbsdLib_macOS_NO_EXPORT inline constexpr EbsdStringLiteral HighToLow("High To Low");
185+
EbsdLib_macOS_NO_EXPORT inline constexpr EbsdStringLiteral UnknownStackingOrder("Unknown Stacking Order");
169186

170187
namespace Utils
171188
{
@@ -223,9 +240,9 @@ inline constexpr uint32_t UnknownCrystalStructure = 999; //!< UnknownCrystalStru
223240

224241
namespace BravaisLattice
225242
{
226-
inline const std::string Unknown("Unknown");
227-
inline const std::string Cubic("Cubic");
228-
inline const std::string Hexagonal("Hexagonal");
243+
EbsdLib_macOS_NO_EXPORT inline constexpr EbsdStringLiteral Unknown("Unknown");
244+
EbsdLib_macOS_NO_EXPORT inline constexpr EbsdStringLiteral Cubic("Cubic");
245+
EbsdLib_macOS_NO_EXPORT inline constexpr EbsdStringLiteral Hexagonal("Hexagonal");
229246
} // namespace BravaisLattice
230247

231248
namespace AngleRepresentation

Source/EbsdLib/Core/EbsdLibDLLExport.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,15 @@ building on Windows.
6969
#define EbsdLib_EXPORT __attribute__((visibility("default")))
7070
#endif
7171
#endif
72+
73+
#if !defined(EbsdLib_macOS_NO_EXPORT)
74+
#if defined(__APPLE__)
75+
#define EbsdLib_macOS_NO_EXPORT __attribute__((visibility("hidden")))
76+
#else
77+
#define EbsdLib_macOS_NO_EXPORT
78+
#endif
79+
#endif
80+
7281
#endif
7382

7483
/* If EbsdLib_EXPORT was never defined, define it here */

Source/EbsdLib/Core/StringLiteral.hpp renamed to Source/EbsdLib/Core/EbsdStringLiteral.hpp

Lines changed: 36 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -25,21 +25,21 @@ constexpr bool HasNullTerminator(const T (&string)[Size]) noexcept
2525
} // namespace detail
2626

2727
/**
28-
* @brief BasicStringLiteral is meant to be a safe container for a string literal allowing for easy access to its size/length.
28+
* @brief BasicEbsdStringLiteral is meant to be a safe container for a string literal allowing for easy access to its size/length.
2929
* This class should always contain a pointer to a static compile time null-terminated string literal.
3030
* Typical usage will be for static string constants. At this time the constructors allow non string literals to be passed in.
3131
* This is undesired behavior, but there is no way to overcome this in C++17 without using character parameter packs which come with their own issues.
3232
* Example:
3333
* @code
34-
* static constexpr StringLiteral k_Foo = "foo";
34+
* static constexpr EbsdStringLiteral k_Foo = "foo";
3535
* @endcode
3636
* @tparam T Character type
3737
*/
3838
template <class T>
39-
class BasicStringLiteral
39+
class BasicEbsdStringLiteral
4040
{
4141
public:
42-
BasicStringLiteral() = delete;
42+
BasicEbsdStringLiteral() = delete;
4343

4444
/**
4545
* @brief Constructor that accepts a string literal of fixed size. Should be made consteval in C++20.
@@ -48,23 +48,23 @@ class BasicStringLiteral
4848
* @return
4949
*/
5050
template <size_t Size>
51-
constexpr BasicStringLiteral(const T (&string)[Size])
51+
constexpr BasicEbsdStringLiteral(const T (&string)[Size])
5252
: m_String(string)
5353
, m_Size(Size)
5454
{
5555
if(!detail::HasNullTerminator(string))
5656
{
57-
throw std::runtime_error("BasicStringLiteral must be null-terminated");
57+
throw std::runtime_error("BasicEbsdStringLiteral must be null-terminated");
5858
}
5959
}
6060

61-
~BasicStringLiteral() noexcept = default;
61+
~BasicEbsdStringLiteral() noexcept = default;
6262

63-
BasicStringLiteral(const BasicStringLiteral&) noexcept = default;
64-
BasicStringLiteral(BasicStringLiteral&&) noexcept = default;
63+
BasicEbsdStringLiteral(const BasicEbsdStringLiteral&) noexcept = default;
64+
BasicEbsdStringLiteral(BasicEbsdStringLiteral&&) noexcept = default;
6565

66-
BasicStringLiteral& operator=(const BasicStringLiteral&) noexcept = default;
67-
BasicStringLiteral& operator=(BasicStringLiteral&&) noexcept = default;
66+
BasicEbsdStringLiteral& operator=(const BasicEbsdStringLiteral&) noexcept = default;
67+
BasicEbsdStringLiteral& operator=(BasicEbsdStringLiteral&&) noexcept = default;
6868

6969
/**
7070
* @brief Returns the c-string pointer.
@@ -133,86 +133,93 @@ class BasicStringLiteral
133133
};
134134

135135
template <class T>
136-
bool operator==(const std::basic_string<T>& lhs, BasicStringLiteral<T> rhs)
136+
bool operator==(const std::basic_string<T>& lhs, BasicEbsdStringLiteral<T> rhs)
137137
{
138138
return lhs == rhs.view();
139139
}
140140

141141
template <class T>
142-
bool operator==(BasicStringLiteral<T> lhs, const std::basic_string<T>& rhs)
142+
bool operator==(BasicEbsdStringLiteral<T> lhs, const std::basic_string<T>& rhs)
143143
{
144144
return rhs == lhs;
145145
}
146146

147147
template <class T>
148-
bool operator!=(const std::basic_string<T>& lhs, BasicStringLiteral<T> rhs)
148+
bool operator!=(const std::basic_string<T>& lhs, BasicEbsdStringLiteral<T> rhs)
149149
{
150150
return lhs != rhs.view();
151151
}
152152

153153
template <class T>
154-
bool operator!=(BasicStringLiteral<T> lhs, const std::basic_string<T>& rhs)
154+
bool operator!=(BasicEbsdStringLiteral<T> lhs, const std::basic_string<T>& rhs)
155155
{
156156
return rhs != lhs;
157157
}
158158

159159
template <class T>
160-
bool operator<(const std::basic_string<T>& lhs, BasicStringLiteral<T> rhs)
160+
bool operator<(const std::basic_string<T>& lhs, BasicEbsdStringLiteral<T> rhs)
161161
{
162162
return lhs < rhs.view();
163163
}
164164

165165
template <class T>
166-
bool operator<(BasicStringLiteral<T> lhs, const std::basic_string<T>& rhs)
166+
bool operator<(BasicEbsdStringLiteral<T> lhs, const std::basic_string<T>& rhs)
167167
{
168168
return lhs.view() < rhs;
169169
}
170170

171171
template <class T>
172-
bool operator>(const std::basic_string<T>& lhs, BasicStringLiteral<T> rhs)
172+
bool operator>(const std::basic_string<T>& lhs, BasicEbsdStringLiteral<T> rhs)
173173
{
174174
return lhs > rhs.view();
175175
}
176176

177177
template <class T>
178-
bool operator>(BasicStringLiteral<T> lhs, const std::basic_string<T>& rhs)
178+
bool operator>(BasicEbsdStringLiteral<T> lhs, const std::basic_string<T>& rhs)
179179
{
180180
return lhs.view() > rhs;
181181
}
182182

183183
template <class T>
184-
bool operator<=(const std::basic_string<T>& lhs, BasicStringLiteral<T> rhs)
184+
bool operator<=(const std::basic_string<T>& lhs, BasicEbsdStringLiteral<T> rhs)
185185
{
186186
return lhs <= rhs.view();
187187
}
188188

189189
template <class T>
190-
bool operator<=(BasicStringLiteral<T> lhs, const std::basic_string<T>& rhs)
190+
bool operator<=(BasicEbsdStringLiteral<T> lhs, const std::basic_string<T>& rhs)
191191
{
192192
return lhs.view() <= rhs;
193193
}
194194

195195
template <class T>
196-
bool operator>=(const std::basic_string<T>& lhs, BasicStringLiteral<T> rhs)
196+
bool operator>=(const std::basic_string<T>& lhs, BasicEbsdStringLiteral<T> rhs)
197197
{
198198
return lhs >= rhs.view();
199199
}
200200

201201
template <class T>
202-
bool operator>=(BasicStringLiteral<T> lhs, const std::basic_string<T>& rhs)
202+
bool operator>=(BasicEbsdStringLiteral<T> lhs, const std::basic_string<T>& rhs)
203203
{
204204
return lhs.view() >= rhs;
205205
}
206206

207-
using StringLiteral = BasicStringLiteral<char>;
208-
using WStringLiteral = BasicStringLiteral<wchar_t>;
209-
using String16Literal = BasicStringLiteral<char16_t>;
210-
using String32Literal = BasicStringLiteral<char32_t>;
207+
template <class T>
208+
std::ostream& operator<<(std::ostream& os, const BasicEbsdStringLiteral<T>& lhs)
209+
{
210+
os << lhs.view();
211+
return os;
212+
}
213+
214+
using EbsdStringLiteral = BasicEbsdStringLiteral<char>;
215+
using WEbsdStringLiteral = BasicEbsdStringLiteral<wchar_t>;
216+
using String16Literal = BasicEbsdStringLiteral<char16_t>;
217+
using String32Literal = BasicEbsdStringLiteral<char32_t>;
211218
} // namespace EbsdLib
212219

213220
#if 0
214221
template <class CharT>
215-
struct fmt::formatter<nx::core::BasicStringLiteral<CharT>>
222+
struct fmt::formatter<nx::core::BasicEbsdStringLiteral<CharT>>
216223
{
217224
static constexpr const CharT* GetFormatString()
218225
{
@@ -239,7 +246,7 @@ struct fmt::formatter<nx::core::BasicStringLiteral<CharT>>
239246
return ctx.begin();
240247
}
241248

242-
typename buffer_context<CharT>::iterator format(const nx::core::BasicStringLiteral<CharT>& p, buffer_context<CharT>& ctx) const
249+
typename buffer_context<CharT>::iterator format(const nx::core::BasicEbsdStringLiteral<CharT>& p, buffer_context<CharT>& ctx) const
243250
{
244251
static constexpr const CharT* formatStr = GetFormatString();
245252

Source/EbsdLib/Core/SourceList.cmake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ set(EbsdLib_${DIR_NAME}_HDRS
1212
${EbsdLibProj_SOURCE_DIR}/Source/EbsdLib/${DIR_NAME}/OrientationRepresentation.h
1313
${EbsdLibProj_SOURCE_DIR}/Source/EbsdLib/${DIR_NAME}/OrientationTransformation.hpp
1414
${EbsdLibProj_SOURCE_DIR}/Source/EbsdLib/${DIR_NAME}/Quaternion.hpp
15+
${EbsdLibProj_SOURCE_DIR}/Source/EbsdLib/${DIR_NAME}/EbsdStringLiteral.hpp
1516
)
1617

1718
set(EbsdLib_${DIR_NAME}_SRCS

0 commit comments

Comments
 (0)