Details
-
Bug
-
Status: Closed (View Workflow)
-
Major
-
Resolution: Fixed
-
10.0(EOL)
Description
This is a split from MDEV-8378, priority and fix version inherited.
Lintian reports: http://labs.seravo.fi/~otto/mariadb-repo/mariadb-10.0-sid-amd64/lintian-0f7cb30.log and https://lintian.debian.org/tags/shlib-calls-exit.html
The listed shared library calls the C library exit() or _exit() functions.
In the case of an error, the library should instead return an appropriate error code to the calling program which can then determine how to handle the error, including performing any required clean-up.
In most cases, removing the call should be discussed with upstream, particularly as it may produce an ABI change.
Severity: wishlist, Certainty: possible
Check: shared-libs, Type: binary, udeb
This tag is marked experimental, which means that the code that generates it is not as well-tested as the rest of Lintian and might still give surprising results. Feel free to ignore experimental tags that do not seem to make sense, though of course bug reports are always welcome.
nm ./storage/innobase/ha_innodb.so|grep exit
U __cxa_atexit@@GLIBC_2.2.5
|
U exit@@GLIBC_2.2.5
|
00000000004738b0 b mutex_exit_count
|
U pthread_exit@@GLIBC_2.2.5
|
000000000013bdf0 t _Z13os_mutex_exitP10os_mutex_t
|
000000000001ec94 t _Z13os_mutex_exitP10os_mutex_t.part.2
|
000000000013c940 t _Z14os_thread_exitPv
|
00000000000b9e50 t _Z15hash_mutex_exitP12hash_table_tm
|
00000000000b9fe0 t _Z19hash_mutex_exit_allP12hash_table_t
|
0000000000159f90 t _Z19pars_exit_statementv
|
00000000000ba050 t _Z23hash_mutex_exit_all_butP12hash_table_tP10ib_mutex_t
|
0000000000078f20 t _Z25dict_mutex_exit_for_mysqlv
|
00000000001a82f0 t _Z26srv_conc_force_exit_innodbP5trx_t
|
0000000000134dd0 T _Z28os_file_handle_error_no_exitPKcS0_m
|
000000000007ccb0 t _Z38dict_table_wait_for_bg_threads_to_exitP12dict_table_tm
|
000000000009ccb0 t _Z9exit_stepP9que_thr_t
|
000000000001d135 t _ZL19pfs_mutex_exit_funcP10ib_mutex_t
|
0000000000077520 t _ZL19pfs_mutex_exit_funcP10ib_mutex_t
|
000000000009cd30 t _ZL19pfs_mutex_exit_funcP10ib_mutex_t
|
00000000000bace0 t _ZL19pfs_mutex_exit_funcP10ib_mutex_t
|
00000000000de530 t _ZL19pfs_mutex_exit_funcP10ib_mutex_t
|
000000000001db33 t _ZL19pfs_mutex_exit_funcP10ib_mutex_t
|
00000000001145f0 t _ZL19pfs_mutex_exit_funcP10ib_mutex_t
|
00000000001a9450 t _ZL19pfs_mutex_exit_funcP10ib_mutex_t
|
00000000001aee80 t _ZL19pfs_mutex_exit_funcP10ib_mutex_t
|
00000000001a96c0 t _ZL21srv_purge_should_exitm
|
0000000000134920 t _ZL30os_file_handle_error_cond_exitPKcS0_mm.constprop.29
|
Attachments
Issue Links
- causes
-
MDEV-13284 mariadb-server: fil_load_single_table_tablespace(): mysqld killed by SIGABRT
-
- Closed
-
- is part of
-
MDEV-8378 Debian: the Lintian complains about many "shlib-calls-exit" in many of the plugins
-
- Closed
-
-
MDEV-10382 Using systemd, mariadb doesn't restart on crashes
-
- Closed
-
In MariaDB 10.1, InnoDB calls exit() in quite a few places:
storage/innobase/api/api0misc.cc:189: exit(1);
storage/innobase/buf/buf0dblwr.cc:232: exit(EXIT_FAILURE);
storage/innobase/buf/buf0dblwr.cc:253: exit(EXIT_FAILURE);
storage/innobase/buf/buf0dblwr.cc:269: exit(EXIT_FAILURE);
storage/innobase/fil/fil0fil.cc:4604: exit(1);
storage/innobase/fts/fts0blex.cc:1615: exit( YY_EXIT_FAILURE );
storage/innobase/fts/fts0tlex.cc:1608: exit( YY_EXIT_FAILURE );
storage/innobase/log/log0log.cc:832: " Calling exit(1).\n",
storage/innobase/log/log0log.cc:835: exit(1);
storage/innobase/log/log0log.cc:2554: exit(1);
storage/innobase/log/log0recv.cc:2038: exit(1);
storage/innobase/log/log0recv.cc:2051: exit(1);
storage/innobase/log/log0recv.cc:2069: exit(1);
storage/innobase/log/log0recv.cc:3637: exit(1);
storage/innobase/log/log0recv.cc:3650: exit(1);
storage/innobase/log/log0recv.cc:3672: exit(1);
storage/innobase/os/os0file.cc:721:Conditionally exits (calling exit(3)) based on should_exit value and the
storage/innobase/os/os0file.cc:730: ibool should_exit, /*!< in: call exit(3) if unknown error
storage/innobase/os/os0file.cc:817: exit(1);
storage/innobase/os/os0thread.cc:162: exit(1);
storage/innobase/os/os0thread.cc:177: exit(1);
storage/innobase/row/row0mysql.cc:665: exit(1);
storage/innobase/row/row0undo.cc:367: exit(1);
storage/innobase/srv/srv0start.cc:603: exit(3); \
storage/innobase/srv/srv0start.cc:2923: exit(1);
This is probably what it should do instead:
storage/innobase/pars/lexyy.cc:967:#define exit(A) ut_error
storage/innobase/pars/lexyy.cc:2916: exit( YY_EXIT_FAILURE );
storage/innobase/pars/pars0lex.l:65:#define exit(A) ut_error
It is rather useless to call exit(), because it would not leave a core dump behind.
It would be better to call abort() so that the issue can be analyzed.
I did some exit() removal in the MySQL 5.7 startup code, but most notably, InnoDB I/O threads will easily call exit() when encountering bad files. This causes occasional debug assertions in other threads, and some workarounds have been added to make such crashes less likely.
The proper fix would be to propagate errors from I/O threads all the way to the client. It would be a huge refactoring task. InnoDB eagerly commits suicide (ut_error) in certain classes of errors (out of memory, corruption) instead of returning an error.
In MariaDB 10.2 (and MySQL 5.7) the only exit() call from InnoDB is in the function srv_fatal_error(), which is called from os_file_handle_error_cond_exit() and innobase_start_or_create_for_mysql(). The latter call could be removed rather easily, but the calls from I/O threads would require considerably more effort.