2019-01-01 07:01:51 +01:00
|
|
|
/* Copyright (C) 2000-2019 Free Software Foundation, Inc.
|
2015-08-05 16:30:57 +02:00
|
|
|
|
|
|
|
This file is part of GDB.
|
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation; either version 3 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
|
|
|
|
2019-01-27 20:51:36 +01:00
|
|
|
#ifndef NAT_GDB_THREAD_DB_H
|
|
|
|
#define NAT_GDB_THREAD_DB_H
|
2015-08-05 16:30:57 +02:00
|
|
|
|
2000-09-03 14:06:58 +02:00
|
|
|
#ifdef HAVE_THREAD_DB_H
|
|
|
|
#include <thread_db.h>
|
|
|
|
#else
|
2013-04-16 20:14:55 +02:00
|
|
|
#include "glibc_thread_db.h"
|
1999-12-22 22:45:38 +01:00
|
|
|
#endif
|
2013-04-16 20:12:14 +02:00
|
|
|
|
|
|
|
#ifndef LIBTHREAD_DB_SO
|
|
|
|
#define LIBTHREAD_DB_SO "libthread_db.so.1"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef LIBTHREAD_DB_SEARCH_PATH
|
|
|
|
/* $sdir appears before $pdir for some minimal security protection:
|
|
|
|
we trust the system libthread_db.so a bit more than some random
|
|
|
|
libthread_db associated with whatever libpthread the app is using. */
|
|
|
|
#define LIBTHREAD_DB_SEARCH_PATH "$sdir:$pdir"
|
|
|
|
#endif
|
C++: dlsym casts in gdb/linux-thread-db.c and gdb/gdbserver/thread-db.c
Implicit void * -> function pointer conversion doesn't work in C++, so
in C++, we need to cast the result of dlsym. This adds a few typedefs
and macros that make this easy. GDBserver's version already had the
CHK macro, so I added it to GDB too.
Tested on x86_64 Fedora 20, native and gdbserver.
gdb/gdbserver/ChangeLog:
2015-08-04 Pedro Alves <palves@redhat.com>
* thread-db.c (struct thread_db): Use new typedefs.
(try_thread_db_load_1): Define local TDB_DLSYM macro and use it in
CHK calls.
(disable_thread_event_reporting): Cast result of dlsym to
destination function pointer type.
(thread_db_mourn): Use td_ta_delete_ftype.
gdb/ChangeLog:
2015-08-04 Pedro Alves <palves@redhat.com>
* nat/gdb_thread_db.h (td_init_ftype, td_ta_new_ftype)
(td_ta_map_lwp2thr_ftype, td_ta_thr_iter_ftype)
(td_ta_event_addr_ftype, td_ta_set_event_ftype)
(td_ta_clear_event_ftype, td_ta_event_getmsg_ftype)
(td_thr_validate_ftype, td_thr_get_info_ftype)
(td_thr_event_enable_ftype, td_thr_tls_get_addr_ftype)
(td_thr_tlsbase_ftype, td_symbol_list_ftype, td_ta_delete_ftype):
New typedefs.
* linux-thread-db.c (struct thread_db_info): Use new typedefs.
(try_thread_db_load_1): Define TDB_VERBOSE_DLSYM, TDB_DLSYM , CHK
local macros and use them instead of verbose_dlsym and dlsym
calls.
2015-08-04 10:39:47 +02:00
|
|
|
|
|
|
|
/* Types of the libthread_db functions. */
|
|
|
|
|
|
|
|
typedef td_err_e (td_init_ftype) (void);
|
|
|
|
|
|
|
|
typedef td_err_e (td_ta_new_ftype) (struct ps_prochandle * ps,
|
|
|
|
td_thragent_t **ta);
|
Fix leak by using td_ta_delete() to deregister target process and deallocate internal process handle.
Valgrind reports the below leak:
==25327== VALGRIND_GDB_ERROR_BEGIN
==25327== 672 bytes in 1 blocks are definitely lost in loss record 2,759 of 3,251
==25327== at 0x4C2E07C: calloc (vg_replace_malloc.c:752)
==25327== by 0x7FDCB3E: ???
==25327== by 0x532A7A: try_thread_db_load_1 (linux-thread-db.c:828)
==25327== by 0x532A7A: try_thread_db_load(char const*, int) (linux-thread-db.c:997)
==25327== by 0x53354D: try_thread_db_load_from_sdir (linux-thread-db.c:1074)
==25327== by 0x53354D: thread_db_load_search (linux-thread-db.c:1129)
==25327== by 0x53354D: thread_db_load() (linux-thread-db.c:1187)
==25327== by 0x611AF1: operator() (functional:2127)
==25327== by 0x611AF1: notify (observable.h:106)
==25327== by 0x611AF1: symbol_file_add_with_addrs(bfd*, char const*, enum_flags<symfile_add_flag>, std::vector<other_sections, std::allocator<other_sections> >*, enum_flags<objfile_flag>, objfile*) (symfile.c:1158)
==25327== by 0x5F5C4A: solib_read_symbols(so_list*, enum_flags<symfile_add_flag>) (solib.c:691)
==25327== by 0x5F6A8B: solib_add(char const*, int, int) (solib.c:1003)
==25327== by 0x5F6BF7: handle_solib_event() (solib.c:1281)
==25327== by 0x3D0A94: bpstat_stop_status(address_space const*, unsigned long, thread_info*, target_waitstatus const*, bpstats*) (breakpoint.c:5417)
==25327== by 0x4FF133: handle_signal_stop(execution_control_state*) (infrun.c:5874)
==25327== by 0x502C29: handle_inferior_event_1 (infrun.c:5300)
==25327== by 0x502C29: handle_inferior_event(execution_control_state*) (infrun.c:5335)
==25327== by 0x5041DB: fetch_inferior_event(void*) (infrun.c:3868)
==25327== by 0x4A1E7C: gdb_wait_for_event(int) (event-loop.c:859)
...
This leak is created because a call to td_ta_new allocates some resources
that must be freed with td_ta_delete, and that was missing.
With this patch, the nr of GDB executions leaking during regression tests
decreases further from 566 to 380.
Note that the gdbserver equivalent code is properly calling
td_ta_delete: see thread_db_mourn in thread-db.c.
Tests run natively on debian/amd64, and run under valgrind.
gdb/ChangeLog
2018-12-08 Philippe Waroquiers <philippe.waroquiers@skynet.be>
* linux-thread-db.c (struct thread_db_info): Add td_ta_delete_p.
(thread_db_err_str): Forward declare.
(delete_thread_db_info): Call td_ta_delete_p if available.
(try_thread_db_load_1): Acquire td_ta_delete address.
* nat/gdb_thread_db.h (td_ta_delete_ftype): Declare.
2018-12-07 18:13:59 +01:00
|
|
|
typedef td_err_e (td_ta_delete_ftype) (td_thragent_t *ta_p);
|
C++: dlsym casts in gdb/linux-thread-db.c and gdb/gdbserver/thread-db.c
Implicit void * -> function pointer conversion doesn't work in C++, so
in C++, we need to cast the result of dlsym. This adds a few typedefs
and macros that make this easy. GDBserver's version already had the
CHK macro, so I added it to GDB too.
Tested on x86_64 Fedora 20, native and gdbserver.
gdb/gdbserver/ChangeLog:
2015-08-04 Pedro Alves <palves@redhat.com>
* thread-db.c (struct thread_db): Use new typedefs.
(try_thread_db_load_1): Define local TDB_DLSYM macro and use it in
CHK calls.
(disable_thread_event_reporting): Cast result of dlsym to
destination function pointer type.
(thread_db_mourn): Use td_ta_delete_ftype.
gdb/ChangeLog:
2015-08-04 Pedro Alves <palves@redhat.com>
* nat/gdb_thread_db.h (td_init_ftype, td_ta_new_ftype)
(td_ta_map_lwp2thr_ftype, td_ta_thr_iter_ftype)
(td_ta_event_addr_ftype, td_ta_set_event_ftype)
(td_ta_clear_event_ftype, td_ta_event_getmsg_ftype)
(td_thr_validate_ftype, td_thr_get_info_ftype)
(td_thr_event_enable_ftype, td_thr_tls_get_addr_ftype)
(td_thr_tlsbase_ftype, td_symbol_list_ftype, td_ta_delete_ftype):
New typedefs.
* linux-thread-db.c (struct thread_db_info): Use new typedefs.
(try_thread_db_load_1): Define TDB_VERBOSE_DLSYM, TDB_DLSYM , CHK
local macros and use them instead of verbose_dlsym and dlsym
calls.
2015-08-04 10:39:47 +02:00
|
|
|
typedef td_err_e (td_ta_map_lwp2thr_ftype) (const td_thragent_t *ta,
|
|
|
|
lwpid_t lwpid, td_thrhandle_t *th);
|
|
|
|
typedef td_err_e (td_ta_thr_iter_ftype) (const td_thragent_t *ta,
|
|
|
|
td_thr_iter_f *callback, void *cbdata_p,
|
|
|
|
td_thr_state_e state, int ti_pri,
|
|
|
|
sigset_t *ti_sigmask_p,
|
|
|
|
unsigned int ti_user_flags);
|
|
|
|
typedef td_err_e (td_ta_event_addr_ftype) (const td_thragent_t *ta,
|
|
|
|
td_event_e event, td_notify_t *ptr);
|
|
|
|
typedef td_err_e (td_ta_set_event_ftype) (const td_thragent_t *ta,
|
|
|
|
td_thr_events_t *event);
|
|
|
|
typedef td_err_e (td_ta_clear_event_ftype) (const td_thragent_t *ta,
|
|
|
|
td_thr_events_t *event);
|
|
|
|
typedef td_err_e (td_ta_event_getmsg_ftype) (const td_thragent_t *ta,
|
|
|
|
td_event_msg_t *msg);
|
|
|
|
|
|
|
|
typedef td_err_e (td_thr_get_info_ftype) (const td_thrhandle_t *th,
|
|
|
|
td_thrinfo_t *infop);
|
|
|
|
typedef td_err_e (td_thr_event_enable_ftype) (const td_thrhandle_t *th,
|
|
|
|
int event);
|
|
|
|
|
|
|
|
typedef td_err_e (td_thr_tls_get_addr_ftype) (const td_thrhandle_t *th,
|
|
|
|
psaddr_t map_address,
|
|
|
|
size_t offset, psaddr_t *address);
|
|
|
|
typedef td_err_e (td_thr_tlsbase_ftype) (const td_thrhandle_t *th,
|
|
|
|
unsigned long int modid,
|
|
|
|
psaddr_t *base);
|
|
|
|
|
|
|
|
typedef const char ** (td_symbol_list_ftype) (void);
|
|
|
|
typedef td_err_e (td_ta_delete_ftype) (td_thragent_t *);
|
2015-08-05 16:30:57 +02:00
|
|
|
|
2019-01-27 20:51:36 +01:00
|
|
|
#endif /* NAT_GDB_THREAD_DB_H */
|