1 //
2 // Copyright 2021 Pixar
3 //
4 // Licensed under the Apache License, Version 2.0 (the "Apache License")
5 // with the following modification; you may not use this file except in
6 // compliance with the Apache License and the following modification to it:
7 // Section 6. Trademarks. is deleted and replaced with:
8 //
9 // 6. Trademarks. This License does not grant permission to use the trade
10 //    names, trademarks, service marks, or product names of the Licensor
11 //    and its affiliates, except as required to comply with Section 4(c) of
12 //    the License and to reproduce the content of the NOTICE file.
13 //
14 // You may obtain a copy of the Apache License at
15 //
16 //     http://www.apache.org/licenses/LICENSE-2.0
17 //
18 // Unless required by applicable law or agreed to in writing, software
19 // distributed under the Apache License with the above modification is
20 // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21 // KIND, either express or implied. See the Apache License for the specific
22 // language governing permissions and limitations under the Apache License.
23 //
24 
25 #include "pxr/pxr.h"
26 #include "pxr/base/tf/api.h"
27 #include "pxr/base/tf/diagnostic.h"
28 #include "pxr/base/tf/getenv.h"
29 #include "pxr/base/tf/exception.h"
30 
31 #include "pxr/base/arch/demangle.h"
32 #include "pxr/base/arch/stackTrace.h"
33 
34 PXR_NAMESPACE_OPEN_SCOPE
35 
TfBaseException(std::string const & message)36 TfBaseException::TfBaseException(std::string const &message)
37     : _message(message)
38 {
39 }
40 
~TfBaseException()41 TfBaseException::~TfBaseException()
42 {
43 }
44 
45 void
_ThrowImpl(TfCallContext const & cc,TfBaseException & exc,TfFunctionRef<void ()> thrower,int skipNCallerFrames)46 TfBaseException::_ThrowImpl(TfCallContext const &cc,
47                             TfBaseException &exc,
48                             TfFunctionRef<void ()> thrower,
49                             int skipNCallerFrames)
50 {
51     if (TfGetenvBool("TF_FATAL_THROW", false)) {
52         TF_FATAL_ERROR("%s (%s thrown)",
53                        exc.what(),
54                        ArchGetDemangled(typeid(exc)).c_str());
55     }
56 
57     // Capture a stack trace here, from the throw-point.
58     static constexpr size_t ThrowStackDepth = 64;
59     // Skip two additional frames, one for this function, and one for
60     // ArchGetStackFrames itself.  Also skip one more if we have a call context,
61     // since that contains all the information for the final throwing frame
62     // itself.
63     int skipFrames = 2 + skipNCallerFrames + (cc ? 1 : 0);
64     ArchGetStackFrames(ThrowStackDepth, skipFrames, &exc._throwStack);
65     exc._callContext = cc;
66     thrower();
67 }
68 
69 const char *
what() const70 TfBaseException::what() const noexcept
71 {
72     return _message.c_str();
73 }
74 
75 PXR_NAMESPACE_CLOSE_SCOPE
76 
77