1 # $NetBSD: t_call_once2.sh,v 1.8 2022/09/29 07:22:49 skrll Exp $ 2 # 3 # Copyright (c) 2018 The NetBSD Foundation, Inc. 4 # All rights reserved. 5 # 6 # Redistribution and use in source and binary forms, with or without 7 # modification, are permitted provided that the following conditions 8 # are met: 9 # 1. Redistributions of source code must retain the above copyright 10 # notice, this list of conditions and the following disclaimer. 11 # 2. Redistributions in binary form must reproduce the above copyright 12 # notice, this list of conditions and the following disclaimer in the 13 # documentation and/or other materials provided with the distribution. 14 # 15 # THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 16 # ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 17 # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 18 # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 19 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 # POSSIBILITY OF SUCH DAMAGE. 26 # 27 28 atf_test_case call_once2 29 call_once2_head() { 30 atf_set "descr" "compile and run std::call_once" 31 atf_set "require.progs" "c++" 32 atf_set "timeout" "600" 33 } 34 35 atf_test_case call_once2_profile 36 call_once2_profile_head() { 37 atf_set "descr" "compile and run std::call_once with profiling option" 38 atf_set "require.progs" "c++" 39 atf_set "timeout" "600" 40 } 41 42 atf_test_case call_once2_pic 43 call_once2_pic_head() { 44 atf_set "descr" "compile and run PIC std::call_once" 45 atf_set "require.progs" "c++" 46 atf_set "timeout" "600" 47 } 48 49 atf_test_case call_once2_pic_32 50 call_once2_pic_32_head() { 51 atf_set "descr" "compile and run 32-bit PIC std::call_once" 52 atf_set "require.progs" "c++" 53 atf_set "timeout" "600" 54 } 55 56 atf_test_case call_once2_pic_profile 57 call_once2_pic_profile_head() { 58 atf_set "descr" "compile and run PIC std::call_once with profiling flag" 59 atf_set "require.progs" "c++" 60 atf_set "timeout" "600" 61 } 62 63 atf_test_case call_once2_pic_profile_32 64 call_once2_pic_profile_32_head() { 65 atf_set "descr" "compile and run 32-bit PIC std::call_once with profiling flag" 66 atf_set "require.progs" "c++" 67 atf_set "timeout" "600" 68 } 69 70 atf_test_case call_once2_profile_32 71 call_once2_profile_32_head() { 72 atf_set "descr" "compile and run 32-bit std::call_once with profiling flag" 73 atf_set "require.progs" "c++" 74 atf_set "timeout" "600" 75 } 76 77 atf_test_case call_once2_pie 78 call_once2_pie_head() { 79 atf_set "descr" "compile and run position independent (PIE) std::call_once" 80 atf_set "require.progs" "c++" 81 atf_set "timeout" "600" 82 } 83 84 atf_test_case call_once2_32 85 call_once2_32_head() { 86 atf_set "descr" "compile and run std::call_once for/in netbsd32 emulation" 87 atf_set "require.progs" "c++ file diff cat" 88 atf_set "timeout" "600" 89 } 90 91 atf_test_case call_once2_static 92 call_once2_static_head() { 93 atf_set "descr" "compile and run std::call_once with static flag" 94 atf_set "require.progs" "c++" 95 atf_set "timeout" "600" 96 } 97 98 call_once2_body() { 99 cat > test.cpp << EOF 100 #include <mutex> 101 #include <thread> 102 #include <iostream> 103 std::once_flag flag, flag_throw; 104 void print_once(void) { std::call_once(flag, [](){ std::cout << "hello, " << std::flush; }); } 105 void throw_once(void) { throw std::exception(); } 106 int main(void) { 107 static const int nr_threads(4); 108 std::thread threads[nr_threads]; 109 110 for (int i = 0; i < nr_threads; ++i) { 111 threads[i] = std::thread(print_once); 112 } 113 for (int i = 0; i < nr_threads; ++i) { 114 threads[i].join(); 115 } 116 117 try { 118 std::call_once(flag_throw, throw_once); 119 } catch (...) { 120 std::cout << "world!" << std::endl; 121 } 122 return 0; 123 } 124 EOF 125 atf_check -s exit:0 -o ignore -e ignore c++ -o call_once2 test.cpp -pthread 126 atf_check -s exit:0 -o inline:"hello, world!\n" ./call_once2 127 } 128 129 call_once2_profile_body() { 130 atf_expect_fail "profiling option doesn't work with shared libraries" 131 cat > test.cpp << EOF 132 #include <mutex> 133 #include <thread> 134 #include <iostream> 135 std::once_flag flag, flag_throw; 136 void print_once(void) { std::call_once(flag, [](){ std::cout << "hello, " << std::flush; }); } 137 void throw_once(void) { throw std::exception(); } 138 int main(void) { 139 static const int nr_threads(4); 140 std::thread threads[nr_threads]; 141 142 for (int i = 0; i < nr_threads; ++i) { 143 threads[i] = std::thread(print_once); 144 } 145 for (int i = 0; i < nr_threads; ++i) { 146 threads[i].join(); 147 } 148 149 try { 150 std::call_once(flag_throw, throw_once); 151 } catch (...) { 152 std::cout << "world!" << std::endl; 153 } 154 return 0; 155 } 156 EOF 157 atf_check -s exit:0 -o ignore -e ignore c++ -pg -o call_once2 test.cpp -pthread 158 atf_check -s exit:0 -o inline:"hello, world!\n" ./call_once2 159 } 160 161 call_once2_profile_32_body() { 162 atf_expect_fail "profiling option doesn't work now" 163 # check whether this arch is 64bit 164 if ! c++ -dM -E - < /dev/null | fgrep -q _LP64; then 165 atf_skip "this is not a 64 bit architecture" 166 fi 167 if ! c++ -m32 -dM -E - < /dev/null 2>/dev/null > ./def32; then 168 atf_skip "c++ -m32 not supported on this architecture" 169 else 170 if fgrep -q _LP64 ./def32; then 171 atf_fail "c++ -m32 does not generate netbsd32 binaries" 172 fi 173 fi 174 175 cat > test.cpp << EOF 176 #include <mutex> 177 #include <thread> 178 #include <iostream> 179 std::once_flag flag, flag_throw; 180 void print_once(void) { std::call_once(flag, [](){ std::cout << "hello, " << std::flush; }); } 181 void throw_once(void) { throw std::exception(); } 182 int main(void) { 183 static const int nr_threads(4); 184 std::thread threads[nr_threads]; 185 186 for (int i = 0; i < nr_threads; ++i) { 187 threads[i] = std::thread(print_once); 188 } 189 for (int i = 0; i < nr_threads; ++i) { 190 threads[i].join(); 191 } 192 193 try { 194 std::call_once(flag_throw, throw_once); 195 } catch (...) { 196 std::cout << "world!" << std::endl; 197 } 198 return 0; 199 } 200 EOF 201 atf_check -s exit:0 -o ignore -e ignore c++ -m32 -pg -o call_once2 test.cpp -pthread 202 atf_check -s exit:0 -o inline:"hello, world!\n" ./call_once2 203 atf_expect_fail "The combination of 32-bit and profiling should be fail" 204 } 205 206 call_once2_pic_body() { 207 cat > test.cpp << EOF 208 #include <stdlib.h> 209 int callpic(void); 210 int main(void) {callpic();exit(0);} 211 EOF 212 cat > pic.cpp << EOF 213 #include <mutex> 214 #include <thread> 215 #include <iostream> 216 std::once_flag flag, flag_throw; 217 void print_once(void) { std::call_once(flag, [](){ std::cout << "hello, " << std::flush; }); } 218 void throw_once(void) { throw std::exception(); } 219 int callpic(void) { 220 static const int nr_threads(4); 221 std::thread threads[nr_threads]; 222 223 for (int i = 0; i < nr_threads; ++i) { 224 threads[i] = std::thread(print_once); 225 } 226 for (int i = 0; i < nr_threads; ++i) { 227 threads[i].join(); 228 } 229 230 try { 231 std::call_once(flag_throw, throw_once); 232 } catch (...) { 233 std::cout << "world!" << std::endl; 234 } 235 return 0; 236 } 237 EOF 238 239 atf_check -s exit:0 -o ignore -e ignore \ 240 c++ -fPIC -shared -o libtest.so pic.cpp 241 atf_check -s exit:0 -o ignore -e ignore \ 242 c++ -o call_once2 test.cpp -L. -ltest -pthread 243 244 export LD_LIBRARY_PATH=. 245 atf_check -s exit:0 -o inline:"hello, world!\n" ./call_once2 246 } 247 248 call_once2_pic_32_body() { 249 # check whether this arch is 64bit 250 if ! c++ -dM -E - < /dev/null | fgrep -q _LP64; then 251 atf_skip "this is not a 64 bit architecture" 252 fi 253 if ! c++ -m32 -dM -E - < /dev/null 2>/dev/null > ./def32; then 254 atf_skip "c++ -m32 not supported on this architecture" 255 else 256 if fgrep -q _LP64 ./def32; then 257 atf_fail "c++ -m32 does not generate netbsd32 binaries" 258 fi 259 fi 260 261 cat > test.cpp << EOF 262 #include <stdlib.h> 263 int callpic(void); 264 int main(void) {callpic();exit(0);} 265 EOF 266 cat > pic.cpp << EOF 267 #include <mutex> 268 #include <thread> 269 #include <iostream> 270 std::once_flag flag, flag_throw; 271 void print_once(void) { std::call_once(flag, [](){ std::cout << "hello, " << std::flush; }); } 272 void throw_once(void) { throw std::exception(); } 273 int callpic(void) { 274 static const int nr_threads(4); 275 std::thread threads[nr_threads]; 276 277 for (int i = 0; i < nr_threads; ++i) { 278 threads[i] = std::thread(print_once); 279 } 280 for (int i = 0; i < nr_threads; ++i) { 281 threads[i].join(); 282 } 283 284 try { 285 std::call_once(flag_throw, throw_once); 286 } catch (...) { 287 std::cout << "world!" << std::endl; 288 } 289 return 0; 290 } 291 EOF 292 293 atf_check -s exit:0 -o ignore -e ignore \ 294 c++ -m32 -fPIC -shared -o libtest.so pic.cpp 295 atf_check -s exit:0 -o ignore -e ignore \ 296 c++ -m32 -o call_once2 test.cpp -L. -ltest -pthread 297 298 export LD_LIBRARY_PATH=. 299 atf_check -s exit:0 -o inline:"hello, world!\n" ./call_once2 300 } 301 302 call_once2_pic_profile_body() { 303 atf_expect_fail "profiling option doesn't work with pic" 304 cat > test.cpp << EOF 305 #include <stdlib.h> 306 int callpic(void); 307 int main(void) {callpic();exit(0);} 308 EOF 309 cat > pic.cpp << EOF 310 #include <mutex> 311 #include <thread> 312 #include <iostream> 313 std::once_flag flag, flag_throw; 314 void print_once(void) { std::call_once(flag, [](){ std::cout << "hello, " << std::flush; }); } 315 void throw_once(void) { throw std::exception(); } 316 int callpic(void) { 317 static const int nr_threads(4); 318 std::thread threads[nr_threads]; 319 320 for (int i = 0; i < nr_threads; ++i) { 321 threads[i] = std::thread(print_once); 322 } 323 for (int i = 0; i < nr_threads; ++i) { 324 threads[i].join(); 325 } 326 327 try { 328 std::call_once(flag_throw, throw_once); 329 } catch (...) { 330 std::cout << "world!" << std::endl; 331 } 332 return 0; 333 } 334 EOF 335 336 atf_check -s exit:0 -o ignore -e ignore \ 337 c++ -pg -fPIC -shared -o libtest.so pic.cpp 338 atf_check -s exit:0 -o ignore -e ignore \ 339 c++ -pg -o call_once2 test.cpp -L. -ltest -pthread 340 341 export LD_LIBRARY_PATH=. 342 atf_check -s exit:0 -o inline:"hello, world!\n" ./call_once2 343 } 344 345 call_once2_pic_profile_32_body() { 346 atf_expect_fail "profiling option doesn't work with shared libraries" 347 # check whether this arch is 64bit 348 if ! c++ -dM -E - < /dev/null | fgrep -q _LP64; then 349 atf_skip "this is not a 64 bit architecture" 350 fi 351 if ! c++ -m32 -dM -E - < /dev/null 2>/dev/null > ./def32; then 352 atf_skip "c++ -m32 not supported on this architecture" 353 else 354 if fgrep -q _LP64 ./def32; then 355 atf_fail "c++ -m32 does not generate netbsd32 binaries" 356 fi 357 fi 358 359 cat > test.cpp << EOF 360 #include <stdlib.h> 361 int callpic(void); 362 int main(void) {callpic();exit(0);} 363 EOF 364 cat > pic.cpp << EOF 365 #include <mutex> 366 #include <thread> 367 #include <iostream> 368 std::once_flag flag, flag_throw; 369 void print_once(void) { std::call_once(flag, [](){ std::cout << "hello, " << std::flush; }); } 370 void throw_once(void) { throw std::exception(); } 371 int callpic(void) { 372 static const int nr_threads(4); 373 std::thread threads[nr_threads]; 374 375 for (int i = 0; i < nr_threads; ++i) { 376 threads[i] = std::thread(print_once); 377 } 378 for (int i = 0; i < nr_threads; ++i) { 379 threads[i].join(); 380 } 381 382 try { 383 std::call_once(flag_throw, throw_once); 384 } catch (...) { 385 std::cout << "world!" << std::endl; 386 } 387 return 0; 388 } 389 EOF 390 391 atf_check -s exit:0 -o ignore -e ignore \ 392 c++ -m32 -pg -fPIC -shared -o libtest.so pic.cpp 393 atf_check -s exit:0 -o ignore -e ignore \ 394 c++ -m32 -pg -o call_once2 test.cpp -L. -ltest -pthread 395 396 export LD_LIBRARY_PATH=. 397 atf_check -s exit:0 -o inline:"hello, world!\n" ./call_once2 398 } 399 400 call_once2_pie_body() { 401 # check whether this arch supports -pie 402 if ! c++ -pie -dM -E - < /dev/null 2>/dev/null >/dev/null; then 403 atf_skip "c++ -pie not supported on this architecture" 404 fi 405 cat > test.cpp << EOF 406 #include <mutex> 407 #include <thread> 408 #include <iostream> 409 std::once_flag flag, flag_throw; 410 void print_once(void) { std::call_once(flag, [](){ std::cout << "hello, " << std::flush; }); } 411 void throw_once(void) { throw std::exception(); } 412 int main(void) { 413 static const int nr_threads(4); 414 std::thread threads[nr_threads]; 415 416 for (int i = 0; i < nr_threads; ++i) { 417 threads[i] = std::thread(print_once); 418 } 419 for (int i = 0; i < nr_threads; ++i) { 420 threads[i].join(); 421 } 422 423 try { 424 std::call_once(flag_throw, throw_once); 425 } catch (...) { 426 std::cout << "world!" << std::endl; 427 } 428 return 0; 429 } 430 EOF 431 atf_check -s exit:0 -o ignore -e ignore c++ -fpie -pie -o call_once2 test.cpp -pthread 432 atf_check -s exit:0 -o inline:"hello, world!\n" ./call_once2 433 } 434 435 call_once2_32_body() { 436 # check whether this arch is 64bit 437 if ! c++ -dM -E - < /dev/null | fgrep -q _LP64; then 438 atf_skip "this is not a 64 bit architecture" 439 fi 440 if ! c++ -m32 -dM -E - < /dev/null 2>/dev/null > ./def32; then 441 atf_skip "c++ -m32 not supported on this architecture" 442 else 443 if fgrep -q _LP64 ./def32; then 444 atf_fail "c++ -m32 does not generate netbsd32 binaries" 445 fi 446 fi 447 448 cat > test.cpp << EOF 449 #include <mutex> 450 #include <thread> 451 #include <iostream> 452 std::once_flag flag, flag_throw; 453 void print_once(void) { std::call_once(flag, [](){ std::cout << "hello, " << std::flush; }); } 454 void throw_once(void) { throw std::exception(); } 455 int main(void) { 456 static const int nr_threads(4); 457 std::thread threads[nr_threads]; 458 459 for (int i = 0; i < nr_threads; ++i) { 460 threads[i] = std::thread(print_once); 461 } 462 for (int i = 0; i < nr_threads; ++i) { 463 threads[i].join(); 464 } 465 466 try { 467 std::call_once(flag_throw, throw_once); 468 } catch (...) { 469 std::cout << "world!" << std::endl; 470 } 471 return 0; 472 } 473 EOF 474 atf_check -s exit:0 -o ignore -e ignore c++ -o call_once2_32 -m32 test.cpp -pthread 475 atf_check -s exit:0 -o ignore -e ignore c++ -o call_once2_64 test.cpp -pthread 476 file -b ./call_once2_32 > ./ftype32 477 file -b ./call_once2_64 > ./ftype64 478 if diff ./ftype32 ./ftype64 >/dev/null; then 479 atf_fail "generated binaries do not differ" 480 fi 481 echo "32bit binaries on this platform are:" 482 cat ./ftype32 483 echo "While native (64bit) binaries are:" 484 cat ./ftype64 485 atf_check -s exit:0 -o inline:"hello, world!\n" ./call_once2_32 486 487 # do another test with static 32bit binaries 488 cat > test.cpp << EOF 489 #include <mutex> 490 #include <thread> 491 #include <iostream> 492 std::once_flag flag, flag_throw; 493 void print_once(void) { std::call_once(flag, [](){ std::cout << "hello, " << std::flush; }); } 494 void throw_once(void) { throw std::exception(); } 495 int main(void) { 496 static const int nr_threads(4); 497 std::thread threads[nr_threads]; 498 499 for (int i = 0; i < nr_threads; ++i) { 500 threads[i] = std::thread(print_once); 501 } 502 for (int i = 0; i < nr_threads; ++i) { 503 threads[i].join(); 504 } 505 506 try { 507 std::call_once(flag_throw, throw_once); 508 } catch (...) { 509 std::cout << "world!" << std::endl; 510 } 511 return 0; 512 } 513 EOF 514 atf_check -s exit:0 -o ignore -e ignore c++ -o call_once2 -m32 -pthread \ 515 -static test.cpp 516 atf_check -s exit:0 -o inline:"hello, world!\n" ./call_once2 517 } 518 519 call_once2_static_body() { 520 cat > test.cpp << EOF 521 #include <mutex> 522 #include <thread> 523 #include <iostream> 524 std::once_flag flag, flag_throw; 525 void print_once(void) { std::call_once(flag, [](){ std::cout << "hello, " << std::flush; }); } 526 void throw_once(void) { throw std::exception(); } 527 int main(void) { 528 static const int nr_threads(4); 529 std::thread threads[nr_threads]; 530 531 for (int i = 0; i < nr_threads; ++i) { 532 threads[i] = std::thread(print_once); 533 } 534 for (int i = 0; i < nr_threads; ++i) { 535 threads[i].join(); 536 } 537 538 try { 539 std::call_once(flag_throw, throw_once); 540 } catch (...) { 541 std::cout << "world!" << std::endl; 542 } 543 return 0; 544 } 545 EOF 546 atf_check -s exit:0 -o ignore -e ignore c++ -static -o call_once2 test.cpp -pthread 547 atf_check -s exit:0 -o inline:"hello, world!\n" ./call_once2 548 } 549 550 atf_init_test_cases() 551 { 552 553 atf_add_test_case call_once2 554 atf_add_test_case call_once2_profile 555 atf_add_test_case call_once2_pic 556 atf_add_test_case call_once2_pie 557 atf_add_test_case call_once2_32 558 atf_add_test_case call_once2_static 559 atf_add_test_case call_once2_pic_32 560 atf_add_test_case call_once2_pic_profile 561 atf_add_test_case call_once2_pic_profile_32 562 atf_add_test_case call_once2_profile_32 563 } 564