Bug Summary

File:thread/tls.c
Warning:line 86, column 13
Using a fixed address is not portable because that address will probably not be valid in all environments or platforms

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name tls.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/home/isvv/naviserver/nsthread -resource-dir /usr/local/lib/clang/15.0.0 -D _FORTIFY_SOURCE=2 -D NDEBUG -D SYSTEM_MALLOC -I ../include -I /usr/include/tcl8.6 -D HAVE_CONFIG_H -internal-isystem /usr/local/lib/clang/15.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/11/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -std=c99 -fdebug-compilation-dir=/home/isvv/naviserver/nsthread -ferror-limit 19 -stack-protector 2 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker alpha -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2022-07-23-130959-11103-1 -x c tls.c
1/*
2 * The contents of this file are subject to the Mozilla Public License
3 * Version 1.1 (the "License"); you may not use this file except in
4 * compliance with the License. You may obtain a copy of the License at
5 * http://mozilla.org/.
6 *
7 * Software distributed under the License is distributed on an "AS IS"
8 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
9 * the License for the specific language governing rights and limitations
10 * under the License.
11 *
12 * The Original Code is AOLserver Code and related documentation
13 * distributed by AOL.
14 *
15 * The Initial Developer of the Original Code is America Online,
16 * Inc. Portions created by AOL are Copyright (C) 1999 America Online,
17 * Inc. All Rights Reserved.
18 *
19 * Alternatively, the contents of this file may be used under the terms
20 * of the GNU General Public License (the "GPL"), in which case the
21 * provisions of GPL are applicable instead of those above. If you wish
22 * to allow use of your version of this file only under the terms of the
23 * GPL and not to allow others to use your version of this file under the
24 * License, indicate your decision by deleting the provisions above and
25 * replace them with the notice and other provisions required by the GPL.
26 * If you do not delete the provisions above, a recipient may use your
27 * version of this file under either the License or the GPL.
28 */
29
30
31/*
32 * tls.c --
33 *
34 * Thread local storage support for nsthreads. Note that the nsthread
35 * library handles thread local storage directly.
36 */
37
38#include "thread.h"
39
40/*
41 * The following global variable specifies the maximum TLS id. Modifying
42 * this value has no effect.
43 */
44
45static uintptr_t nsThreadMaxTls = NS_THREAD_MAXTLS100;
46
47/*
48 * Static functions defined in this file.
49 */
50
51static Ns_TlsCleanup *cleanupProcs[NS_THREAD_MAXTLS100];
52
53
54/*
55 *----------------------------------------------------------------------
56 *
57 * Ns_TlsAlloc --
58 *
59 * Allocate the next tls id.
60 *
61 * Results:
62 * None.
63 *
64 * Side effects:
65 * Id is set in given tlsPtr.
66 *
67 *----------------------------------------------------------------------
68 */
69
70void
71Ns_TlsAlloc(Ns_Tls *keyPtr, Ns_TlsCleanup *cleanup)
72{
73 static uintptr_t nextkey = 1u;
74 uintptr_t key;
75
76 NS_NONNULL_ASSERT(keyPtr != NULL)((void) (0));
77
78 Ns_MasterLock();
79 if (nextkey == nsThreadMaxTls) {
1
Assuming 'nextkey' is not equal to 'nsThreadMaxTls'
2
Taking false branch
80 Tcl_Panic("Ns_TlsAlloc: exceeded max tls: %" PRIuPTR"l" "u", nsThreadMaxTls);
81 }
82 key = nextkey++;
83 cleanupProcs[key] = cleanup;
84 Ns_MasterUnlock();
85
86 *keyPtr = (void *) key;
3
Using a fixed address is not portable because that address will probably not be valid in all environments or platforms
87}
88
89
90/*
91 *----------------------------------------------------------------------
92 *
93 * Ns_TlsSet --
94 *
95 * Set the value for a threads tls slot.
96 *
97 * Results:
98 * None.
99 *
100 * Side effects:
101 * None.
102 *
103 *----------------------------------------------------------------------
104 */
105
106void
107Ns_TlsSet(const Ns_Tls *keyPtr, void *value)
108{
109 uintptr_t key;
110
111 NS_NONNULL_ASSERT(keyPtr != NULL)((void) (0));
112
113 key = (uintptr_t) *keyPtr;
114 if (key < 1 || key >= NS_THREAD_MAXTLS100) {
115 Tcl_Panic("Ns_TlsSet: invalid key: %" PRIuPTR"l" "u"
116 ": should be between 1 and %" PRIuPTR"l" "u",
117 key, nsThreadMaxTls);
118 } else {
119 void **slots = NsGetTls();
120
121 slots[key] = value;
122 }
123}
124
125
126/*
127 *----------------------------------------------------------------------
128 *
129 * Ns_TlsGet --
130 *
131 * Get this thread's value in a tls slot.
132 *
133 * Results:
134 * Pointer in slot.
135 *
136 * Side effects:
137 * None.
138 *
139 *----------------------------------------------------------------------
140 */
141
142void *
143Ns_TlsGet(const Ns_Tls *keyPtr)
144{
145 uintptr_t key;
146 void *result;
147
148 NS_NONNULL_ASSERT(keyPtr != NULL)((void) (0));
149
150 key = (uintptr_t) *keyPtr;
151 if (key < 1 || key >= NS_THREAD_MAXTLS100) {
152 result = NULL((void*)0);
153 Tcl_Panic("Ns_TlsGet: invalid key: %" PRIuPTR"l" "u"
154 ": should be between 1 and %" PRIuPTR"l" "u",
155 key, nsThreadMaxTls);
156 } else {
157 void **slots = NsGetTls();
158
159 result = slots[key];
160 }
161 return result;
162}
163
164
165/*
166 *----------------------------------------------------------------------
167 *
168 * NsCleanupTls --
169 *
170 * Cleanup thread local storage in LIFO order for an exiting thread.
171 * Note the careful use of the counters to keep iterating over the
172 * list, up to 5 times, until all TLS values are NULL. This emulates
173 * the Pthread TLS behavior which catches a destructor inadvertently
174 * calling a library which resets a TLS value after it has been destroyed.
175 *
176 * Results:
177 * None.
178 *
179 * Side effects:
180 * Cleanup procs are invoked for non-null values.
181 *
182 *----------------------------------------------------------------------
183 */
184
185void
186NsCleanupTls(void **slots)
187{
188 NS_NONNULL_ASSERT(slots != NULL)((void) (0));
189
190 if (
191#if defined(TCL_IS_FIXED)
192 1
193#else
194 NS_finalshutdown != 1
195#endif
196 ) {
197 int tries, retry;
198
199 tries = 0;
200 do {
201 int i;
202
203 retry = 0;
204 i = NS_THREAD_MAXTLS100;
205 while (i-- > 0) {
206 if (cleanupProcs[i] != NULL((void*)0) && slots[i] != NULL((void*)0)) {
207 void *arg;
208
209 arg = slots[i];
210 slots[i] = NULL((void*)0);
211 (*cleanupProcs[i])(arg);
212 retry = 1;
213 }
214 }
215 } while (retry && tries++ < 5);
216 }
217}
218
219/*
220 * Local Variables:
221 * mode: c
222 * c-basic-offset: 4
223 * fill-column: 78
224 * indent-tabs-mode: nil
225 * End:
226 */