]>
Commit | Line | Data |
---|---|---|
9e78f6f6 | 1 | /* Test that loading libpthread does not break ld.so exceptions (bug 16628). |
d614a753 | 2 | Copyright (C) 2016-2020 Free Software Foundation, Inc. |
9e78f6f6 FW |
3 | This file is part of the GNU C Library. |
4 | ||
5 | The GNU C Library is free software; you can redistribute it and/or | |
6 | modify it under the terms of the GNU Lesser General Public | |
7 | License as published by the Free Software Foundation; either | |
8 | version 2.1 of the License, or (at your option) any later version. | |
9 | ||
10 | The GNU C Library is distributed in the hope that it will be useful, | |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 | Lesser General Public License for more details. | |
14 | ||
15 | You should have received a copy of the GNU Lesser General Public | |
16 | License along with the GNU C Library; if not, see | |
5a82c748 | 17 | <https://www.gnu.org/licenses/>. */ |
9e78f6f6 FW |
18 | |
19 | #include <dlfcn.h> | |
20 | #include <signal.h> | |
21 | #include <stdio.h> | |
22 | #include <string.h> | |
23 | #include <sys/wait.h> | |
24 | #include <unistd.h> | |
25 | ||
26 | static int | |
27 | do_test (void) | |
28 | { | |
29 | void *handle = dlopen ("tst-latepthreadmod.so", RTLD_LOCAL | RTLD_LAZY); | |
30 | if (handle == NULL) | |
31 | { | |
32 | printf ("error: dlopen failed: %s\n", dlerror ()); | |
33 | return 1; | |
34 | } | |
35 | void *ptr = dlsym (handle, "trigger_dynlink_failure"); | |
36 | if (ptr == NULL) | |
37 | { | |
38 | printf ("error: dlsym failed: %s\n", dlerror ()); | |
39 | return 1; | |
40 | } | |
41 | int (*func) (void) = ptr; | |
42 | ||
43 | /* Run the actual test in a subprocess, to capture the error. */ | |
44 | int fds[2]; | |
45 | if (pipe (fds) < 0) | |
46 | { | |
47 | printf ("error: pipe: %m\n"); | |
48 | return 1; | |
49 | } | |
50 | pid_t pid = fork (); | |
51 | if (pid < 0) | |
52 | { | |
53 | printf ("error: fork: %m\n"); | |
54 | return 1; | |
55 | } | |
56 | else if (pid == 0) | |
57 | { | |
58 | if (dup2 (fds[1], STDERR_FILENO) < 0) | |
59 | _exit (2); | |
60 | /* Trigger an abort. */ | |
61 | func (); | |
62 | _exit (3); | |
63 | } | |
64 | /* NB: This assumes that the abort message is so short that the pipe | |
65 | does not block. */ | |
66 | int status; | |
67 | if (waitpid (pid, &status, 0) < 0) | |
68 | { | |
69 | printf ("error: waitpid: %m\n"); | |
70 | return 1; | |
71 | } | |
72 | ||
73 | /* Check the printed error message. */ | |
74 | if (close (fds[1]) < 0) | |
75 | { | |
76 | printf ("error: close: %m\n"); | |
77 | return 1; | |
78 | } | |
79 | char buf[512]; | |
80 | /* Leave room for the NUL terminator. */ | |
81 | ssize_t ret = read (fds[0], buf, sizeof (buf) - 1); | |
82 | if (ret < 0) | |
83 | { | |
84 | printf ("error: read: %m\n"); | |
85 | return 1; | |
86 | } | |
87 | if (ret > 0 && buf[ret - 1] == '\n') | |
88 | --ret; | |
89 | buf[ret] = '\0'; | |
90 | printf ("info: exit status: %d, message: %s\n", status, buf); | |
91 | if (strstr (buf, "undefined symbol: this_function_is_not_defined") == NULL) | |
92 | { | |
93 | printf ("error: message does not contain expected string\n"); | |
94 | return 1; | |
95 | } | |
96 | if (!WIFEXITED (status) || WEXITSTATUS (status) != 127) | |
97 | { | |
98 | printf ("error: unexpected process exit status\n"); | |
99 | return 1; | |
100 | } | |
101 | return 0; | |
102 | } | |
103 | ||
36fe25fd | 104 | #include <support/test-driver.c> |