Skip to content

Commit 70abc97

Browse files
committed
Bug#37278704: Do not throw exceptions from destructors
Note: throwing from destructors was the root cause for the bug.
1 parent 883d20d commit 70abc97

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+136
-100
lines changed

cdk/core/session.cc

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ struct Session_builder
5353

5454
struct ReportStatus
5555
{
56-
//False if not able to connect, true if all is good.
56+
// False if not able to connect, true if all is good.
5757
option_t m_status = false;
5858
Session_builder::ep_filter_t m_filter;
5959
size_t m_id;
@@ -63,6 +63,12 @@ struct Session_builder
6363
, m_id(id)
6464
{}
6565

66+
/*
67+
Note: The only reason for ReportStatus object is to use RAII to invoke
68+
m_filter() on destruction to report session creation status. So this
69+
is part of logic of methods that use such object and as such is allowed
70+
to throw errors from the dtor.
71+
*/
6672

6773
~ReportStatus()
6874
{
@@ -481,7 +487,7 @@ Session::Session(ds::Unix_socket &ds, const ds::Unix_socket::Options &options)
481487
#endif //#ifndef WIN32
482488

483489

484-
Session::~Session()
490+
Session::~Session() NOEXCEPT
485491
{
486492
delete m_session;
487493
delete m_connection;

cdk/foundation/connection_openssl.cc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -265,12 +265,12 @@ class connection_TLS_impl
265265
, m_options(options)
266266
{}
267267

268-
~connection_TLS_impl()
268+
~connection_TLS_impl() NOEXCEPT
269269
{
270270
if (m_tls)
271271
{
272272
/*
273-
Server is expecting a SSL quiet shutdown.
273+
Server is expecting a SSL quiet shutdown.
274274
*/
275275
SSL_set_quiet_shutdown(m_tls, 1);
276276
SSL_shutdown(m_tls);
@@ -697,7 +697,7 @@ class safe_X509
697697
: m_X509(obj)
698698
{}
699699

700-
~safe_X509()
700+
~safe_X509() NOEXCEPT
701701
{
702702
if (std::is_same<X, X509>::value)
703703
{

cdk/foundation/connection_tcpip.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ class Socket_system_initializer
138138
detail::initialize_socket_system();
139139
}
140140

141-
~Socket_system_initializer()
141+
~Socket_system_initializer() NOEXCEPT
142142
{
143143
try
144144
{

cdk/foundation/connection_tcpip_base.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,9 +110,9 @@ class Socket_base::Impl
110110
return detail::poll_one(m_sock, detail::POLL_MODE_WRITE, false) > 0;
111111
}
112112

113-
virtual ~Impl()
113+
virtual ~Impl() NOEXCEPT
114114
{
115-
close();
115+
try { close(); } catch (...) {}
116116
}
117117

118118
virtual void do_connect() =0;

cdk/foundation/socket_detail.cc

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -643,7 +643,7 @@ Socket connect(const char *host_name, unsigned short port,
643643
struct AddrInfoGuard
644644
{
645645
addrinfo* list;
646-
~AddrInfoGuard() { freeaddrinfo(list); }
646+
~AddrInfoGuard() NOEXCEPT { freeaddrinfo(list); }
647647
}
648648
guard = { host_list };
649649

@@ -916,6 +916,13 @@ void recv(Socket socket, byte *buffer, size_t buffer_size)
916916

917917
size_t bytes_received = 0;
918918

919+
/*
920+
Note: In presence of timeouts recv_some() can return 0 which would lead
921+
to an infinite loop here! See also bug#37278716.
922+
923+
A solution would be to throw error if timeout was hit?
924+
*/
925+
919926
while (bytes_received != buffer_size)
920927
bytes_received += recv_some(socket, buffer + bytes_received, buffer_size - bytes_received, true);
921928
}

cdk/include/mysql/cdk/api/document.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ class Any_processor
107107

108108
virtual Doc_prc* doc() =0;
109109

110-
virtual ~Any_processor() {}
110+
virtual ~Any_processor() NOEXCEPT {}
111111
};
112112

113113

@@ -156,7 +156,7 @@ class Doc_processor
156156
*/
157157
virtual Any_prc* key_val(const string &key) =0;
158158

159-
virtual ~Doc_processor() {}
159+
virtual ~Doc_processor() NOEXCEPT {}
160160
};
161161

162162

cdk/include/mysql/cdk/api/obj_ref.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ class Ref_base
4747
{
4848
public:
4949

50-
virtual ~Ref_base() {}
50+
virtual ~Ref_base() NOEXCEPT {}
5151

5252
virtual const string name() const =0;
5353
virtual const string orig_name() const { return name(); }

cdk/include/mysql/cdk/api/session.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ class Session
4444
{
4545
public:
4646

47-
virtual ~Session() {}
47+
virtual ~Session() NOEXCEPT {}
4848

4949
// Check if given session is valid. Function is_valid() performs a lightweight, local check while
5050
// check_valid() might communicate with the data store to perform this check.

cdk/include/mysql/cdk/codec.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -371,7 +371,7 @@ class Codec<TYPE_FLOAT>
371371

372372
Codec(const Format_info &fi) : Codec_base<TYPE_FLOAT>(fi) {}
373373

374-
virtual ~Codec() {}
374+
virtual ~Codec() NOEXCEPT {}
375375

376376
virtual size_t from_bytes(bytes buf, float &val);
377377
virtual size_t from_bytes(bytes buf, double &val);

cdk/include/mysql/cdk/common.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,7 @@ class JSON_processor
414414
virtual void num(double) =0;
415415
virtual void yesno(bool) =0;
416416

417-
virtual ~JSON_processor() {}
417+
virtual ~JSON_processor() NOEXCEPT {}
418418
};
419419

420420
typedef api::Doc_base<JSON_processor> JSON;

cdk/include/mysql/cdk/data_source.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ namespace ds {
5252

5353
struct Attr_processor
5454
{
55-
virtual ~Attr_processor() {}
55+
virtual ~Attr_processor() NOEXCEPT {}
5656
virtual void attr(const string &key, const string &val)=0;
5757
};
5858

@@ -90,7 +90,7 @@ class Options
9090
}
9191
}
9292

93-
virtual ~Options() {}
93+
virtual ~Options() NOEXCEPT {}
9494

9595
virtual const string& user() const { return m_usr; }
9696
virtual const std::string* password() const
@@ -171,7 +171,7 @@ class TCPIP
171171
throw_error("invalid empty host name");
172172
}
173173

174-
virtual ~TCPIP() {}
174+
virtual ~TCPIP() NOEXCEPT {}
175175

176176
virtual unsigned short port() const { return m_port; }
177177
virtual const std::string& host() const { return m_host; }
@@ -346,7 +346,7 @@ class Unix_socket
346346
throw_error("invalid empty socket path");
347347
}
348348

349-
virtual ~Unix_socket() {}
349+
virtual ~Unix_socket() NOEXCEPT {}
350350

351351
virtual const std::string& path() const { return m_path; }
352352
};
@@ -386,7 +386,7 @@ class TCPIP : public cdk::ds::mysqlx::TCPIP
386386
: cdk::ds::mysqlx::TCPIP(_host, _port)
387387
{}
388388

389-
virtual ~TCPIP() {}
389+
virtual ~TCPIP() NOEXCEPT {}
390390

391391
typedef ds::Options<Protocol_options> Options;
392392
};

cdk/include/mysql/cdk/foundation/async.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ class Async_op_base : nocopy
5050
{
5151
public:
5252

53-
virtual ~Async_op_base() {}
53+
virtual ~Async_op_base() NOEXCEPT {}
5454

5555
virtual bool is_completed() const =0;
5656

cdk/include/mysql/cdk/foundation/codec.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ class String_codec
7171
{
7272
public:
7373

74-
virtual ~String_codec() {}
74+
virtual ~String_codec() NOEXCEPT {}
7575

7676
//virtual size_t measure(const string&) =0;
7777
virtual size_t from_bytes(bytes, string&) =0;
@@ -165,7 +165,7 @@ class Number_codec
165165
{
166166
public:
167167

168-
virtual ~Number_codec() {}
168+
virtual ~Number_codec() NOEXCEPT {}
169169

170170
virtual size_t from_bytes(bytes buf, int8_t &val) =0;
171171
virtual size_t from_bytes(bytes buf, int16_t &val) =0;

cdk/include/mysql/cdk/foundation/connection_tcpip.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ class IO_error : public Error_class<IO_error>
107107
: Error_base(NULL, io_error(num))
108108
{}
109109

110-
virtual ~IO_error() throw() {}
110+
virtual ~IO_error() NOEXCEPT {}
111111

112112
};
113113

cdk/include/mysql/cdk/foundation/diagnostics.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ class Diagnostic_iterator : public api::Diagnostics::Iterator
223223
: m_entries(NULL), m_level(Severity::ERROR)
224224
{}
225225

226-
virtual ~Diagnostic_iterator() {}
226+
virtual ~Diagnostic_iterator() NOEXCEPT {}
227227

228228
const Entry& entry()
229229
{
@@ -265,8 +265,10 @@ class Diagnostic_arena
265265
: m_it(m_entries, Severity::ERROR)
266266
{}
267267

268-
virtual ~Diagnostic_arena()
269-
{ clear(); }
268+
virtual ~Diagnostic_arena() NOEXCEPT
269+
{
270+
try { clear(); } catch (...) {}
271+
}
270272

271273

272274
/*

cdk/include/mysql/cdk/foundation/error_category.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ const error_category& posix_error_category();
144144
struct error_category_##EC : public cdk::foundation::error_category_base \
145145
{ \
146146
error_category_##EC() {} \
147-
const char* name() const throw() { return "cdk-" #EC; } \
147+
const char* name() const NOEXCEPT { return "cdk-" #EC; } \
148148
std::string message(int code) const \
149149
{ CDK_ERROR_SWITCH(NS, EC, code); } \
150150
cdk::foundation::error_condition do_default_error_condition(int) const; \

cdk/include/mysql/cdk/foundation/opaque_impl.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ class opaque_impl
171171

172172
protected:
173173

174-
virtual ~opaque_impl();
174+
virtual ~opaque_impl() NOEXCEPT;
175175

176176
// Default constructor: uses default constructor of internal implementation type.
177177

cdk/include/mysql/cdk/foundation/opaque_impl.i

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ namespace foundation {
129129
namespace cdk { \
130130
namespace foundation { \
131131
template<> \
132-
opaque_impl<X>::~opaque_impl() { delete m_impl; } \
132+
opaque_impl<X>::~opaque_impl() NOEXCEPT { delete m_impl; } \
133133
}} // cdk::foundation
134134

135135
#define IMPL_DEFAULT(X) \

cdk/include/mysql/cdk/foundation/stream.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ class Connection
7575
, public Output_stream
7676
{
7777
public:
78-
virtual ~Connection() {}
78+
virtual ~Connection() NOEXCEPT {}
7979
virtual void connect() =0;
8080
virtual void close() =0;
8181
virtual bool is_closed() const =0;

cdk/include/mysql/cdk/foundation/variant.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -356,9 +356,9 @@ class variant
356356
return *this;
357357
}
358358

359-
~variant()
359+
~variant() NOEXCEPT
360360
{
361-
Base::destroy();
361+
try { Base::destroy(); } catch (...) {}
362362
}
363363

364364
operator bool()

cdk/include/mysql/cdk/mysqlx/common.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -95,13 +95,13 @@ class Server_error
9595

9696
typedef protocol::mysqlx::sql_state_t sql_state_t;
9797

98-
Server_error(unsigned num, sql_state_t, const string& desc = string()) throw()
98+
Server_error(unsigned num, sql_state_t, const string& desc = string()) NOEXCEPT
9999
: Error_base(NULL, server_error(static_cast<int>(num)), desc)
100100
{
101101
assert(num < (unsigned)std::numeric_limits<int>::max());
102102
}
103103

104-
virtual ~Server_error() throw() {}
104+
virtual ~Server_error() NOEXCEPT {}
105105

106106
};
107107

@@ -115,7 +115,7 @@ class Server_prepare_error
115115

116116
Server_prepare_error(
117117
unsigned num, sql_state_t sql_state, const string& desc = string()
118-
) throw()
118+
) NOEXCEPT
119119
: Error_base(NULL, num, sql_state , desc)
120120
{}
121121
};
@@ -128,7 +128,7 @@ class Server_expectation_error
128128

129129
typedef protocol::mysqlx::sql_state_t sql_state_t;
130130

131-
Server_expectation_error(const string& desc) throw()
131+
Server_expectation_error(const string& desc) NOEXCEPT
132132
: Error_base(NULL, 5168, sql_state_t("HY000") , desc)
133133
{}
134134
};

cdk/include/mysql/cdk/mysqlx/result.h

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -446,12 +446,21 @@ class Stmt_op
446446
assert(m_session);
447447
}
448448

449-
virtual ~Stmt_op()
449+
virtual ~Stmt_op() NOEXCEPT
450450
{
451-
discard();
452-
wait();
453-
if (m_session)
454-
m_session->deregister_stmt(this);
451+
try
452+
{
453+
discard();
454+
wait();
455+
}
456+
catch (...) {}
457+
458+
try
459+
{
460+
if (m_session)
461+
m_session->deregister_stmt(this);
462+
}
463+
catch (...) {}
455464
}
456465

457466
Session& get_session()
@@ -812,7 +821,7 @@ class Cursor
812821
public:
813822

814823
Cursor(const std::shared_ptr<Stmt_op> &reply);
815-
~Cursor();
824+
~Cursor() NOEXCEPT;
816825

817826
void get_rows(mysqlx::Row_processor& rp);
818827
void get_rows(mysqlx::Row_processor& rp, row_count_t limit);

cdk/include/mysql/cdk/mysqlx/session.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ class SessionAuth
148148
public:
149149

150150
SessionAuth(Session&, const char *method);
151-
virtual ~SessionAuth() {}
151+
virtual ~SessionAuth() NOEXCEPT {}
152152

153153
/*
154154
Authentication data to be sent in the AuthenticateStart message,
@@ -294,7 +294,7 @@ class Session
294294
*/
295295
Compression_type::value negotiate_compression(const std::vector<compression_algorithm_t>& algorithms);
296296

297-
virtual ~Session();
297+
virtual ~Session() NOEXCEPT;
298298

299299
/*
300300
Check if given session is valid. Function is_valid() performs

0 commit comments

Comments
 (0)