summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBryan Cantrill <bryan@joyent.com>2014-02-14 23:29:13 +0000
committerBryan Cantrill <bryan@joyent.com>2014-02-14 23:29:13 +0000
commit2595e72f8dc69331e3e5c34ed5dfd4d9b3ad9666 (patch)
treea7806020fcd3a5b7461896a664496666ed4c3811
parentf913af9a89ea504956f64f20c14085d2ff148261 (diff)
downloadillumos-joyent-2595e72f8dc69331e3e5c34ed5dfd4d9b3ad9666.tar.gz
OS-2749 mdb choked on core file from newer platform
Reviewed by: Robert Mustacchi <rm@joyent.com>
-rw-r--r--usr/src/lib/libc_db/common/thread_db.c30
1 files changed, 28 insertions, 2 deletions
diff --git a/usr/src/lib/libc_db/common/thread_db.c b/usr/src/lib/libc_db/common/thread_db.c
index 77c44b2782..b58971dfec 100644
--- a/usr/src/lib/libc_db/common/thread_db.c
+++ b/usr/src/lib/libc_db/common/thread_db.c
@@ -24,6 +24,10 @@
* Use is subject to license terms.
*/
+/*
+ * Copyright (c) 2014, Joyent, Inc. All rights reserved.
+ */
+
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
@@ -146,6 +150,7 @@ static td_err_e
td_read_uberdata(td_thragent_t *ta_p)
{
struct ps_prochandle *ph_p = ta_p->ph_p;
+ int i;
if (ta_p->model == PR_MODEL_NATIVE) {
uberdata_t uberdata;
@@ -163,12 +168,10 @@ td_read_uberdata(td_thragent_t *ta_p)
if (ps_pdread(ph_p, (psaddr_t)uberdata.tdb.tdb_events,
ta_p->tdb_events, sizeof (ta_p->tdb_events)) != PS_OK)
return (TD_DBERR);
-
} else {
#if defined(_LP64) && defined(_SYSCALL32)
uberdata32_t uberdata;
caddr32_t tdb_events[TD_MAX_EVENT_NUM - TD_MIN_EVENT_NUM + 1];
- int i;
if (ps_pdread(ph_p, ta_p->uberdata_addr,
&uberdata, sizeof (uberdata)) != PS_OK)
@@ -189,6 +192,29 @@ td_read_uberdata(td_thragent_t *ta_p)
return (TD_DBERR);
#endif
}
+
+ /*
+ * Unfortunately, we are (implicitly) assuming that our uberdata
+ * definition precisely matches that of our target. If this is not
+ * true (that is, if we're examining a core file from a foreign
+ * system that has a different definition of uberdata), the failure
+ * modes can be frustratingly non-explicit. In an effort to catch
+ * this upon initialization (when the debugger may still be able to
+ * opt for another thread model or may be able to fail explicitly), we
+ * check that each of our tdb_events points to valid memory (these are
+ * putatively text upon which a breakpoint can be issued), with the
+ * hope that this is enough of a self-consistency check to lead to
+ * explicit failure on a mismatch.
+ */
+ for (i = 0; i < TD_MAX_EVENT_NUM - TD_MIN_EVENT_NUM + 1; i++) {
+ uint8_t check;
+
+ if (ps_pdread(ph_p, (psaddr_t)ta_p->tdb_events[i],
+ &check, sizeof (check)) != PS_OK) {
+ return (TD_DBERR);
+ }
+ }
+
if (ta_p->hash_size != 1) { /* multi-threaded */
ta_p->initialized = 2;
ta_p->single_lwpid = 0;