Skip to content

Commit 03f0452

Browse files
ivanivanov884jeffmahoney
authored andcommitted
gdb-rhbz1156192-recursive-dlopen-test.patch
;; Testcase for '[SAP] Recursive dlopen causes SAP HANA installer to ;; crash.' (RH BZ 1156192). ;;=fedoratest
1 parent 47e8f07 commit 03f0452

File tree

4 files changed

+321
-0
lines changed

4 files changed

+321
-0
lines changed
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/* Testcase for recursive dlopen calls.
2+
3+
Copyright (C) 2014 Free Software Foundation, Inc.
4+
5+
This file is part of GDB.
6+
7+
This program is free software; you can redistribute it and/or modify
8+
it under the terms of the GNU General Public License as published by
9+
the Free Software Foundation; either version 3 of the License, or
10+
(at your option) any later version.
11+
12+
This program is distributed in the hope that it will be useful,
13+
but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
GNU General Public License for more details.
16+
17+
You should have received a copy of the GNU General Public License
18+
along with this program. If not, see <http://www.gnu.org/licenses/>. */
19+
20+
/* This test was copied from glibc's testcase called
21+
<dlfcn/tst-rec-dlopen.c> and related files. */
22+
23+
#include <stdio.h>
24+
#include <stdlib.h>
25+
26+
void
27+
bar (void)
28+
{
29+
printf ("Called bar.\n");
30+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/* Testcase for recursive dlopen calls.
2+
3+
Copyright (C) 2014 Free Software Foundation, Inc.
4+
5+
This file is part of GDB.
6+
7+
This program is free software; you can redistribute it and/or modify
8+
it under the terms of the GNU General Public License as published by
9+
the Free Software Foundation; either version 3 of the License, or
10+
(at your option) any later version.
11+
12+
This program is distributed in the hope that it will be useful,
13+
but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
GNU General Public License for more details.
16+
17+
You should have received a copy of the GNU General Public License
18+
along with this program. If not, see <http://www.gnu.org/licenses/>. */
19+
20+
/* This test was copied from glibc's testcase called
21+
<dlfcn/tst-rec-dlopen.c> and related files. */
22+
23+
#include <stdio.h>
24+
#include <stdlib.h>
25+
26+
void
27+
foo (void)
28+
{
29+
printf ("Called foo.\n");
30+
}
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
/* Testcase for recursive dlopen calls.
2+
3+
Copyright (C) 2014 Free Software Foundation, Inc.
4+
5+
This file is part of GDB.
6+
7+
This program is free software; you can redistribute it and/or modify
8+
it under the terms of the GNU General Public License as published by
9+
the Free Software Foundation; either version 3 of the License, or
10+
(at your option) any later version.
11+
12+
This program is distributed in the hope that it will be useful,
13+
but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
GNU General Public License for more details.
16+
17+
You should have received a copy of the GNU General Public License
18+
along with this program. If not, see <http://www.gnu.org/licenses/>. */
19+
20+
/* This test was copied from glibc's testcase called
21+
<dlfcn/tst-rec-dlopen.c> and related files. */
22+
23+
#include <stdio.h>
24+
#include <stdlib.h>
25+
#include <malloc.h>
26+
#include <dlfcn.h>
27+
28+
#define DSO "gdb-rhbz1156192-recursive-dlopen-libfoo.so"
29+
#define FUNC "foo"
30+
31+
#define DSO1 "gdb-rhbz1156192-recursive-dlopen-libbar.so"
32+
#define FUNC1 "bar"
33+
34+
/* Prototype for my hook. */
35+
void *custom_malloc_hook (size_t, const void *);
36+
37+
/* Pointer to old malloc hooks. */
38+
void *(*old_malloc_hook) (size_t, const void *);
39+
40+
/* Call function func_name in DSO dso_name via dlopen. */
41+
void
42+
call_func (const char *dso_name, const char *func_name)
43+
{
44+
int ret;
45+
void *dso;
46+
void (*func) (void);
47+
char *err;
48+
49+
/* Open the DSO. */
50+
dso = dlopen (dso_name, RTLD_NOW|RTLD_GLOBAL);
51+
if (dso == NULL)
52+
{
53+
err = dlerror ();
54+
fprintf (stderr, "%s\n", err);
55+
exit (1);
56+
}
57+
/* Clear any errors. */
58+
dlerror ();
59+
60+
/* Lookup func. */
61+
*(void **) (&func) = dlsym (dso, func_name);
62+
if (func == NULL)
63+
{
64+
err = dlerror ();
65+
if (err != NULL)
66+
{
67+
fprintf (stderr, "%s\n", err);
68+
exit (1);
69+
}
70+
}
71+
/* Call func twice. */
72+
(*func) ();
73+
74+
/* Close the library and look for errors too. */
75+
ret = dlclose (dso);
76+
if (ret != 0)
77+
{
78+
err = dlerror ();
79+
fprintf (stderr, "%s\n", err);
80+
exit (1);
81+
}
82+
83+
}
84+
85+
/* Empty hook that does nothing. */
86+
void *
87+
custom_malloc_hook (size_t size, const void *caller)
88+
{
89+
void *result;
90+
/* Restore old hooks. */
91+
__malloc_hook = old_malloc_hook;
92+
/* First call a function in another library via dlopen. */
93+
call_func (DSO1, FUNC1);
94+
/* Called recursively. */
95+
result = malloc (size);
96+
/* Restore new hooks. */
97+
__malloc_hook = custom_malloc_hook;
98+
return result;
99+
}
100+
101+
int
102+
main (void)
103+
{
104+
105+
/* Save old hook. */
106+
old_malloc_hook = __malloc_hook;
107+
/* Install new hook. */
108+
__malloc_hook = custom_malloc_hook;
109+
110+
/* Attempt to dlopen a shared library. This dlopen will
111+
trigger an access to the ld.so.cache, and that in turn
112+
will require a malloc to duplicate data in the cache.
113+
The malloc will call our malloc hook which calls dlopen
114+
recursively, and upon return of this dlopen the non-ref
115+
counted ld.so.cache mapping will be unmapped. We will
116+
return to the original dlopen and crash trying to access
117+
dlopened data. */
118+
call_func (DSO, FUNC);
119+
120+
/* Restore old hook. */
121+
__malloc_hook = old_malloc_hook;
122+
123+
return 0;
124+
}
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
# Copyright 2014 Free Software Foundation, Inc.
2+
#
3+
# This program is free software; you can redistribute it and/or modify
4+
# it under the terms of the GNU General Public License as published by
5+
# the Free Software Foundation; either version 3 of the License, or
6+
# (at your option) any later version.
7+
#
8+
# This program is distributed in the hope that it will be useful,
9+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+
# GNU General Public License for more details.
12+
#
13+
# You should have received a copy of the GNU General Public License
14+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
15+
16+
if { [skip_shlib_tests] } {
17+
return 0
18+
}
19+
20+
# Library foo
21+
set libname1 "gdb-rhbz1156192-recursive-dlopen-libfoo"
22+
set srcfile_lib1 ${srcdir}/${subdir}/${libname1}.c
23+
set binfile_lib1 [standard_output_file ${libname1}.so]
24+
# Library bar
25+
set libname2 "gdb-rhbz1156192-recursive-dlopen-libbar"
26+
set srcfile_lib2 ${srcdir}/${subdir}/${libname2}.c
27+
set binfile_lib2 [standard_output_file ${libname2}.so]
28+
29+
set testfile "gdb-rhbz1156192-recursive-dlopen"
30+
set srcfile ${testfile}.c
31+
set executable ${testfile}
32+
set binfile [standard_output_file ${executable}]
33+
34+
if { [gdb_compile_shlib ${srcfile_lib1} ${binfile_lib1} \
35+
{ debug "additional_flags=-fPIC" }] != "" } {
36+
untested "Could not compile ${binfile_lib1}"
37+
return -1
38+
}
39+
40+
if { [gdb_compile_shlib ${srcfile_lib2} ${binfile_lib2} \
41+
{ debug "additional_flags=-fPIC" }] != "" } {
42+
untested "Could not compile ${binfile_lib2}"
43+
return -1
44+
}
45+
46+
if { [prepare_for_testing ${testfile}.exp ${executable} ${srcfile} \
47+
[ list debug shlib_load "additional_flags=-Wno-deprecated-declarations" ]] } {
48+
untested "Could not compile ${executable}"
49+
return -1
50+
}
51+
52+
proc do_test { has_libfoo has_libbar } {
53+
global hex binfile_lib2 binfile_lib1 gdb_prompt
54+
set libbar_match "[string_to_regexp $binfile_lib2]"
55+
set libfoo_match "[string_to_regexp $binfile_lib1]"
56+
57+
gdb_test_multiple "info shared" "info shared" {
58+
-re ".*$libfoo_match\r\n.*$libbar_match\(\r\n.*Shared library is missing\)?.*\r\n${gdb_prompt} $" {
59+
if { $has_libfoo && $has_libbar } {
60+
pass "matched libfoo and libbar"
61+
} else {
62+
fail "matched libfoo and libbar (has_libfoo = $has_libfoo, has_libbar = $has_libbar)"
63+
}
64+
}
65+
-re ".*$libfoo_match\(\r\n.*Shared library is missing\)?.*\r\n${gdb_prompt} $" {
66+
if { $has_libfoo && !$has_libbar } {
67+
pass "matched libfoo"
68+
} else {
69+
fail "matched libfoo (has_libfoo = $has_libfoo, has_libbar = $has_libbar)"
70+
}
71+
}
72+
-re ".*$libbar_match\(\r\n.*Shared library is missing\)?.*\r\n${gdb_prompt} $" {
73+
if { $has_libbar && !$has_libfoo } {
74+
pass "matched libbar"
75+
} else {
76+
fail "matched libbar (has_libfoo = $has_libfoo, has_libbar = $has_libbar)"
77+
}
78+
}
79+
"\r\n${gdb_prompt} $" {
80+
if { !$has_libfoo && !$has_libbar } {
81+
pass "did not match libfoo nor libbar"
82+
} else {
83+
fail "did not match libfoo nor libbar (has_libfoo = $has_libfoo, has_libbar = $has_libbar)"
84+
}
85+
}
86+
}
87+
}
88+
89+
proc test_stop_on_solib_events { } {
90+
set pass 0
91+
# This variable holds the information about whether libfoo and
92+
# libbar (respectively) are expected in the "info shared" output.
93+
set solib_event_order { { 0 0 } { 0 0 } { 0 0 } { 0 1 } \
94+
{ 0 1 } { 0 0 } { 0 0 } { 0 1 } \
95+
{ 0 1 } { 0 0 } { 0 0 } { 0 1 } \
96+
{ 0 1 } { 0 0 } { 0 0 1 } { 1 1 } \
97+
{ 1 1 } { 1 0 } { 1 0 } { 1 1 } \
98+
{ 1 1 } { 1 0 1 } { 1 0 } { 1 0 } }
99+
100+
with_test_prefix "stop-on-solib-events" {
101+
gdb_test_no_output "set stop-on-solib-events 1" "setting stop-on-solib-events"
102+
103+
gdb_run_cmd
104+
foreach l $solib_event_order {
105+
incr pass
106+
with_test_prefix "pass #$pass" {
107+
set should_be_corrupted [expr 0+0[lindex $l 2]]
108+
do_test [lindex $l 0] [lindex $l 1]
109+
set test "continue"
110+
global gdb_prompt
111+
gdb_test_multiple $test $test {
112+
-re "\r\nwarning: Corrupted shared library list:.*\r\nStopped due to shared library event.*\r\n$gdb_prompt $" {
113+
set corrupted 1
114+
pass $test
115+
}
116+
-re "\r\nStopped due to shared library event.*\r\n$gdb_prompt $" {
117+
set corrupted 0
118+
pass $test
119+
}
120+
}
121+
set test "corrupted=$corrupted but should_be_corrupted=$should_be_corrupted"
122+
if {$corrupted == $should_be_corrupted} {
123+
pass $test
124+
} else {
125+
fail $test
126+
}
127+
}
128+
}
129+
# In the last pass we do not expect to see libfoo or libbar.
130+
incr pass
131+
with_test_prefix "pass #$pass" {
132+
do_test 0 0
133+
}
134+
}
135+
}
136+
137+
test_stop_on_solib_events

0 commit comments

Comments
 (0)