Bug Summary

File:pr/Linux4.19_x86_64_gcc_glibc_PTH_64_DBG.OBJ/pr/tests/../../../pr/tests/sel_spd.c
Warning:line 468, column 5
Null pointer passed to 1st parameter expecting 'nonnull'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name sel_spd.c -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 -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/var/lib/jenkins/workspace/nss-scan-build/nspr/Linux4.19_x86_64_gcc_glibc_PTH_64_DBG.OBJ/pr/tests -fcoverage-compilation-dir=/var/lib/jenkins/workspace/nss-scan-build/nspr/Linux4.19_x86_64_gcc_glibc_PTH_64_DBG.OBJ/pr/tests -resource-dir /usr/lib/llvm-18/lib/clang/18 -U NDEBUG -D DEBUG_jenkins -D PACKAGE_NAME="" -D PACKAGE_TARNAME="" -D PACKAGE_VERSION="" -D PACKAGE_STRING="" -D PACKAGE_BUGREPORT="" -D PACKAGE_URL="" -D DEBUG=1 -D HAVE_VISIBILITY_HIDDEN_ATTRIBUTE=1 -D HAVE_VISIBILITY_PRAGMA=1 -D XP_UNIX=1 -D _GNU_SOURCE=1 -D HAVE_FCNTL_FILE_LOCKING=1 -D HAVE_POINTER_LOCALTIME_R=1 -D LINUX=1 -D HAVE_DLADDR=1 -D HAVE_GETTID=1 -D HAVE_LCHOWN=1 -D HAVE_SETPRIORITY=1 -D HAVE_STRERROR=1 -D HAVE_SYSCALL=1 -D HAVE_SECURE_GETENV=1 -D _REENTRANT=1 -D FORCE_PR_LOG -D _PR_PTHREADS -U HAVE_CVAR_BUILT_ON_SEM -I /var/lib/jenkins/workspace/nss-scan-build/nss/../dist/Linux4.19_x86_64_gcc_glibc_PTH_64_DBG.OBJ/include -I ../../../pr/include -I ../../../pr/include/private -internal-isystem /usr/lib/llvm-18/lib/clang/18/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -ferror-limit 19 -fvisibility=hidden -fgnuc-version=4.2.1 -fno-inline -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2024-05-18-082241-28900-1 -x c ../../../pr/tests/sel_spd.c
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2/* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6/*
7 * Test the speed of select within NSPR
8 *
9 */
10
11#include "nspr.h"
12#include "prpriv.h"
13
14#include <stdlib.h>
15#include <stdio.h>
16#include <errno(*__errno_location ()).h>
17#include <string.h>
18
19#if defined(XP_UNIX1)
20#include <unistd.h>
21#endif
22
23#ifdef DEBUG1
24#define PORT_INC_DO+100 +100
25#else
26#define PORT_INC_DO+100
27#endif
28#ifdef IS_64
29#define PORT_INC_3264+200 +200
30#else
31#define PORT_INC_3264+200
32#endif
33
34#define PORT_BASE19000 +100 +200 19000 PORT_INC_DO+100 PORT_INC_3264+200
35
36typedef struct timer_slot_t {
37 unsigned long d_connect;
38 unsigned long d_cl_data;
39 unsigned long d_sv_data;
40 unsigned long d_close;
41 unsigned long d_total;
42 unsigned long requests;
43} timer_slot_t;
44
45static long _iterations = 5;
46static long _client_data = 8192;
47
48static long _server_data = (128*1024);
49static long _threads_max = 10, _threads = 10;
50
51static int verbose=0;
52static PRMonitor *exit_cv;
53static long _thread_exit_count;
54static timer_slot_t *timer_data;
55static PRThreadScope scope1, scope2;
56
57void tally_results(int);
58
59/* return the diff in microseconds */
60unsigned long _delta(PRIntervalTime *start, PRIntervalTime *stop)
61{
62 /*
63 * Will C do the right thing with unsigned arithemtic?
64 */
65 return PR_IntervalToMicroseconds(*stop - *start);
66}
67
68int _readn(PRFileDesc *sock, char *buf, int len)
69{
70 int rem;
71 int bytes;
72
73 for (rem=len; rem; rem -= bytes) {
74 bytes = PR_Recv(sock, buf+len-rem, rem, 0, PR_INTERVAL_NO_TIMEOUT0xffffffffUL);
75 if (bytes <= 0) {
76 return -1;
77 }
78 }
79 return len;
80}
81
82void
83_thread_exit(int id)
84{
85 PR_EnterMonitor(exit_cv);
86#ifdef DEBUG1
87 fprintf(stdoutstdout, "Thread %d EXIT\n", id);
88#endif
89
90 _thread_exit_count--;
91 if (_thread_exit_count == 0) {
92#ifdef DEBUG1
93 fprintf(stdoutstdout, "Thread %d EXIT triggered notify\n", id);
94#endif
95 PR_Notify(exit_cv);
96 }
97 PR_ExitMonitor(exit_cv);
98}
99
100void
101_server_thread(void *arg_id)
102{
103 void _client_thread(void *);
104 int *id = (int *)arg_id;
105 PRFileDesc *sock;
106 PRSocketOptionData sockopt;
107 PRNetAddr sa;
108 PRFileDesc * newsock;
109 char *data_buffer = NULL((void*)0);
110 int data_buffer_size;
111 int index;
112 PRIntervalTime start,
113 connect_done,
114 read_done,
115 write_done,
116 close_done;
117
118
119#ifdef DEBUG1
120 fprintf(stdoutstdout, "server thread %d alive\n", *id);
121#endif
122
123 data_buffer_size = (_client_data>_server_data?_client_data:_server_data);
124
125 if ( (data_buffer = (char *)PR_Malloc(data_buffer_size * sizeof(char))) == NULL((void*)0) ) {
126 fprintf(stderrstderr, "Error creating buffer in server thread %d\n", *id);
127 goto done;
128 }
129
130
131 if ( (sock = PR_NewTCPSocket()) == NULL((void*)0)) {
132 fprintf(stderrstderr, "Error creating socket in server thread %d\n", *id);
133 goto done;
134 }
135
136 sockopt.option = PR_SockOpt_Reuseaddr;
137 sockopt.value.reuse_addr = PR_TRUE1;
138 if ( PR_SetSocketOption(sock, &sockopt) == PR_FAILURE) {
139 fprintf(stderrstderr, "Error setting socket option in server thread %d\n", *id);
140 goto done;
141 }
142
143 memset(&sa, 0, sizeof(sa));
144 sa.inet.family = PR_AF_INET2;
145 sa.inet.port = PR_htons(PORT_BASE19000 +100 +200 + *id);
146 sa.inet.ip = PR_htonl(PR_INADDR_ANY((in_addr_t) 0x00000000));
147
148 if ( PR_Bind(sock, &sa) < 0) {
149 fprintf(stderrstderr, "Error binding socket in server thread %d errno = %d\n", *id, errno(*__errno_location ()));
150 goto done;
151 }
152
153 if ( PR_Listen(sock, 32) < 0 ) {
154 fprintf(stderrstderr, "Error listening to socket in server thread %d\n", *id);
155 goto done;
156 }
157
158 /* Tell the client to start */
159 if ( PR_CreateThread(PR_USER_THREAD,
160 _client_thread,
161 id,
162 PR_PRIORITY_NORMAL,
163 scope2,
164 PR_UNJOINABLE_THREAD,
165 0) == NULL((void*)0)) {
166 fprintf(stderrstderr, "Error creating client thread %d\n", *id);
167 }
168
169 for (index = 0; index< _iterations; index++) {
170
171#ifdef DEBUG1
172 fprintf(stdoutstdout, "server thread %d loop %d\n", *id, index);
173#endif
174
175 start = PR_IntervalNow();
176
177 if ( (newsock = PR_Accept(sock, &sa,
178 PR_INTERVAL_NO_TIMEOUT0xffffffffUL)) == NULL((void*)0)) {
179 fprintf(stderrstderr, "Error accepting connection %d in server thread %d\n",
180 index, *id);
181 goto done;
182 }
183#ifdef DEBUG1
184 fprintf(stdoutstdout, "server thread %d got connection %d\n", *id, newsock);
185#endif
186
187
188 connect_done = PR_IntervalNow();
189
190 if ( _readn(newsock, data_buffer, _client_data) < _client_data) {
191 fprintf(stderrstderr, "Error reading client data for iteration %d in server thread %d\n", index, *id );
192 goto done;
193 }
194
195#ifdef DEBUG1
196 fprintf(stdoutstdout, "server thread %d read %d bytes\n", *id, _client_data);
197#endif
198 read_done = PR_IntervalNow();
199
200 if ( PR_Send(newsock, data_buffer, _server_data, 0,
201 PR_INTERVAL_NO_TIMEOUT0xffffffffUL) < _server_data) {
202 fprintf(stderrstderr, "Error sending client data for iteration %d in server thread %d\n", index, *id );
203 goto done;
204 }
205
206#ifdef DEBUG1
207 fprintf(stdoutstdout, "server thread %d write %d bytes\n", *id, _server_data);
208#endif
209
210 write_done = PR_IntervalNow();
211
212 PR_Close(newsock);
213
214 close_done = PR_IntervalNow();
215
216 timer_data[2*(*id)].d_connect += _delta(&start, &connect_done);
217 timer_data[2*(*id)].d_cl_data += _delta(&connect_done, &read_done);
218 timer_data[2*(*id)].d_sv_data += _delta(&read_done, &write_done);
219 timer_data[2*(*id)].d_close += _delta(&write_done, &close_done);
220 timer_data[2*(*id)].d_total += _delta(&start, &close_done);
221 timer_data[2*(*id)].requests++;
222
223
224#ifdef DEBUG1
225 fprintf(stdoutstdout, "server: %d %d %d %d %d\n",
226 _delta(&start, &connect_done), _delta(&connect_done, &read_done),
227 _delta(&read_done, &write_done), _delta(&write_done, &close_done),
228 _delta(&start, &close_done));
229#endif
230 }
231
232done:
233 if (data_buffer != NULL((void*)0)) {
234 PR_Free (data_buffer);
235 }
236 if (sock) {
237 PR_Close(sock);
238 }
239 _thread_exit(*id);
240 return;
241}
242
243void
244_client_thread(void *arg_id)
245{
246 int *id = (int *)arg_id;
247 int index;
248 PRNetAddr sa;
249 PRFileDesc *sock_h;
250 char *data_buffer = NULL((void*)0);
251 int data_buffer_size;
252 int bytes;
253 PRIntervalTime start,
254 connect_done,
255 read_done,
256 write_done,
257 close_done;
258 PRStatus rv;
259
260#ifdef DEBUG1
261 fprintf(stdoutstdout, "client thread %d alive\n", *id);
262#endif
263
264 data_buffer_size = (_client_data>_server_data?_client_data:_server_data);
265
266 if ( (data_buffer = (char *)PR_Malloc(data_buffer_size * sizeof(char))) == NULL((void*)0)) {
267 fprintf(stderrstderr, "Error creating buffer in server thread %d\n", *id);
268 goto done;
269 }
270
271 memset(&sa, 0, sizeof(sa));
272 rv = PR_InitializeNetAddr(PR_IpAddrLoopback, PORT_BASE19000 +100 +200 + *id, &sa);
273 PR_ASSERT(PR_SUCCESS == rv)((PR_SUCCESS == rv)?((void)0):PR_Assert("PR_SUCCESS == rv","../../../pr/tests/sel_spd.c"
,273))
;
274
275 for (index = 0; index< _iterations; index++) {
276
277#ifdef DEBUG1
278 fprintf(stdoutstdout, "client thread %d loop %d\n", *id, index);
279#endif
280
281 start = PR_IntervalNow();
282 if ( (sock_h = PR_NewTCPSocket()) == NULL((void*)0)) {
283 fprintf(stderrstderr, "Error creating socket %d in client thread %d\n",
284 index, *id);
285 goto done;
286 }
287
288#ifdef DEBUG1
289 fprintf(stdoutstdout, "client thread %d socket created %d\n", *id, sock_h);
290#endif
291
292 if ( PR_Connect(sock_h, &sa,
293 PR_INTERVAL_NO_TIMEOUT0xffffffffUL) < 0) {
294 fprintf(stderrstderr, "Error accepting connection %d in client thread %d\n",
295 index, *id);
296 goto done;
297 }
298
299#ifdef DEBUG1
300 fprintf(stdoutstdout, "client thread %d socket connected %d\n", *id, sock_h);
301#endif
302
303 connect_done = PR_IntervalNow();
304 if ( PR_Send(sock_h, data_buffer, _client_data, 0,
305 PR_INTERVAL_NO_TIMEOUT0xffffffffUL) < _client_data) {
306 fprintf(stderrstderr, "Error sending client data for iteration %d in client thread %d\n", index, *id );
307 goto done;
308 }
309
310#ifdef DEBUG1
311 fprintf(stdoutstdout, "client thread %d socket wrote %d\n", *id, _client_data);
312#endif
313
314 write_done = PR_IntervalNow();
315 if ( (bytes = _readn(sock_h, data_buffer, _server_data)) < _server_data) {
316 fprintf(stderrstderr, "Error reading server data for iteration %d in client thread %d (read %d bytes)\n", index, *id, bytes );
317 goto done;
318 }
319
320#ifdef DEBUG1
321 fprintf(stdoutstdout, "client thread %d socket read %d\n", *id, _server_data);
322#endif
323
324 read_done = PR_IntervalNow();
325 PR_Close(sock_h);
326 close_done = PR_IntervalNow();
327
328 timer_data[2*(*id)+1].d_connect += _delta(&start, &connect_done);
329 timer_data[2*(*id)+1].d_cl_data += _delta(&connect_done, &write_done);
330 timer_data[2*(*id)+1].d_sv_data += _delta(&write_done, &read_done);
331 timer_data[2*(*id)+1].d_close += _delta(&read_done, &close_done);
332 timer_data[2*(*id)+1].d_total += _delta(&start, &close_done);
333 timer_data[2*(*id)+1].requests++;
334 }
335done:
336 if (data_buffer != NULL((void*)0)) {
337 PR_Free (data_buffer);
338 }
339 _thread_exit(*id);
340
341 return;
342}
343
344static
345void do_work(void)
346{
347 int index;
348
349 _thread_exit_count = _threads * 2;
350 for (index=0; index<_threads; index++) {
351 int *id = (int *)PR_Malloc(sizeof(int));
352
353 *id = index;
354
355 if ( PR_CreateThread(PR_USER_THREAD,
356 _server_thread,
357 id,
358 PR_PRIORITY_NORMAL,
359 scope1,
360 PR_UNJOINABLE_THREAD,
361 0) == NULL((void*)0)) {
362 fprintf(stderrstderr, "Error creating server thread %d\n", index);
363 }
364 }
365
366 PR_EnterMonitor(exit_cv);
367 while (_thread_exit_count > 0) {
368 PR_Wait(exit_cv, PR_INTERVAL_NO_TIMEOUT0xffffffffUL);
369 }
370 PR_ExitMonitor(exit_cv);
371
372 fprintf(stdoutstdout, "TEST COMPLETE!\n");
373
374 tally_results(verbose);
375
376}
377
378static void do_workUU(void)
379{
380 scope1 = PR_LOCAL_THREAD;
381 scope2 = PR_LOCAL_THREAD;
382 do_work();
383}
384
385static void do_workUK(void)
386{
387 scope1 = PR_LOCAL_THREAD;
388 scope2 = PR_GLOBAL_THREAD;
389 do_work();
390}
391
392static void do_workKU(void)
393{
394 scope1 = PR_GLOBAL_THREAD;
395 scope2 = PR_LOCAL_THREAD;
396 do_work();
397}
398
399static void do_workKK(void)
400{
401 scope1 = PR_GLOBAL_THREAD;
402 scope2 = PR_GLOBAL_THREAD;
403 do_work();
404}
405
406
407
408static void Measure(void (*func)(void), const char *msg)
409{
410 PRIntervalTime start, stop;
411 double d;
412
413 start = PR_IntervalNow();
414 (*func)();
415 stop = PR_IntervalNow();
416
417 d = (double)PR_IntervalToMicroseconds(stop - start);
418
419 printf("%40s: %6.2f usec\n", msg, d / _iterations);
420}
421
422
423int main(int argc, char **argv)
424{
425#if defined(XP_UNIX1) || defined(XP_OS2)
426 int opt;
427 PR_IMPORT_DATA(char *)extern __attribute__((visibility("default"))) char * optarg;
428#endif
429
430#if defined(XP_UNIX1) || defined(XP_OS2)
431 while ( (opt = getopt(argc, argv, "c:s:i:t:v")) != EOF(-1)) {
1
Assuming the condition is false
2
Loop condition is false. Execution continues on line 454
432 switch(opt) {
433 case 'i':
434 _iterations = atoi(optarg);
435 break;
436 case 't':
437 _threads_max = _threads = atoi(optarg);
438 break;
439 case 'c':
440 _client_data = atoi(optarg);
441 break;
442 case 's':
443 _server_data = atoi(optarg);
444 break;
445 case 'v':
446 verbose = 1;
447 break;
448 default:
449 break;
450 }
451 }
452#endif
453
454 PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
455 PR_STDIO_INIT();
456
457 fprintf(stdoutstdout, "Running test for %d iterations with %d simultaneous threads.\n",
458 _iterations, _threads);
459 fprintf(stdoutstdout, "\tWill send %d bytes of client data and %d bytes of server data\n",
460 _client_data, _server_data);
461
462 if ( (exit_cv = PR_NewMonitor()) == NULL((void*)0)) {
3
Assuming the condition is false
4
Taking false branch
463 fprintf(stderrstderr, "Error creating monitor for exit cv\n");
464 }
465 if ( (timer_data = (timer_slot_t *)PR_Malloc(2*_threads * sizeof(timer_slot_t))) == NULL((void*)0)) {
5
Value assigned to 'timer_data'
6
Assuming pointer value is null
7
Taking true branch
466 fprintf(stderrstderr, "error allocating thread time results array\n");
467 }
468 memset(timer_data, 0, 2*_threads*sizeof(timer_slot_t));
8
Null pointer passed to 1st parameter expecting 'nonnull'
469
470 Measure(do_workUU, "select loop user/user");
471 Measure(do_workUK, "select loop user/kernel");
472 Measure(do_workKU, "select loop kernel/user");
473 Measure(do_workKK, "select loop kernel/kernel");
474
475
476 return 0;
477}
478
479void
480tally_results(int verbose)
481{
482 int index;
483 unsigned long tot_connect = 0;
484 unsigned long tot_cl_data = 0;
485 unsigned long tot_sv_data = 0;
486 unsigned long tot_close = 0;
487 unsigned long tot_all = 0;
488 unsigned long tot_requests = 0;
489
490 fprintf(stdoutstdout, "Server results:\n\n");
491 for (index=0; index<_threads_max*2; index+=2) {
492
493 if (verbose)
494 fprintf(stdoutstdout, "server thread %u\t%u\t%u\t%u\t%u\t%u\t%u\n",
495 index, timer_data[index].requests, timer_data[index].d_connect,
496 timer_data[index].d_cl_data, timer_data[index].d_sv_data,
497 timer_data[index].d_close, timer_data[index].d_total);
498
499 tot_connect += timer_data[index].d_connect / _threads;
500 tot_cl_data += timer_data[index].d_cl_data / _threads;
501 tot_sv_data += timer_data[index].d_sv_data / _threads;
502 tot_close += timer_data[index].d_close / _threads;
503 tot_all += timer_data[index].d_total / _threads;
504 tot_requests += timer_data[index].requests / _threads;
505 }
506 fprintf(stdoutstdout, "----------\n");
507 fprintf(stdoutstdout, "server per thread totals %u\t%u\t%u\t%u\t%u\n",
508 tot_requests, tot_connect, tot_cl_data, tot_sv_data, tot_close);
509 fprintf(stdoutstdout, "server per thread elapsed time %u\n", tot_all);
510 fprintf(stdoutstdout, "----------\n");
511
512 tot_connect = tot_cl_data = tot_sv_data = tot_close = tot_all = tot_requests = 0;
513 fprintf(stdoutstdout, "Client results:\n\n");
514 for (index=1; index<_threads_max*2; index+=2) {
515
516 if (verbose)
517 fprintf(stdoutstdout, "client thread %u\t%u\t%u\t%u\t%u\t%u\t%u\n",
518 index, timer_data[index].requests, timer_data[index].d_connect,
519 timer_data[index].d_cl_data, timer_data[index].d_sv_data,
520 timer_data[index].d_close, timer_data[index].d_total);
521
522 tot_connect += timer_data[index].d_connect / _threads;
523 tot_cl_data += timer_data[index].d_cl_data / _threads;
524 tot_sv_data += timer_data[index].d_sv_data / _threads;
525 tot_close += timer_data[index].d_close / _threads;
526 tot_all += timer_data[index].d_total / _threads;
527 tot_requests += timer_data[index].requests / _threads;
528 }
529 fprintf(stdoutstdout, "----------\n");
530 fprintf(stdoutstdout, "client per thread totals %u\t%u\t%u\t%u\t%u\n",
531 tot_requests, tot_connect, tot_cl_data, tot_sv_data, tot_close);
532 fprintf(stdoutstdout, "client per thread elapsed time %u\n", tot_all);
533}
534