A couple of READ calls in td_sync_info() were reading into a

pthread_spin_t variable (4 bytes) but telling read that they were
reading sizeof(struct pthread_spinlock_st) (12 bytes). This led to
overwriting other things on the stack, like the return address. Oops.

Fix by changing READ call here (and elsewhere, for future safety) to:
  READ(,, &variable, sizeof(variable))
instead of
  READ(,, &variable, sizeof(type)).

Fixes a crash in gdb when running "thread examine all" reported by
Bill Studenmund.
This commit is contained in:
nathanw 2003-04-05 01:39:13 +00:00
parent eb1f0e9546
commit 64b72cb09f
1 changed files with 26 additions and 26 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: pthread_dbg.c,v 1.5 2003/03/08 08:03:37 lukem Exp $ */ /* $NetBSD: pthread_dbg.c,v 1.6 2003/04/05 01:39:13 nathanw Exp $ */
/*- /*-
* Copyright (c) 2002 Wasabi Systems, Inc. * Copyright (c) 2002 Wasabi Systems, Inc.
@ -36,7 +36,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__RCSID("$NetBSD: pthread_dbg.c,v 1.5 2003/03/08 08:03:37 lukem Exp $"); __RCSID("$NetBSD: pthread_dbg.c,v 1.6 2003/04/05 01:39:13 nathanw Exp $");
#include <stddef.h> #include <stddef.h>
#include <stdlib.h> #include <stdlib.h>
@ -202,7 +202,7 @@ td_thr_info(td_thread_t *thread, td_thread_info_t *info)
info->thread_addr = thread->addr; info->thread_addr = thread->addr;
if ((val = READ(thread->proc, if ((val = READ(thread->proc,
thread->addr + offsetof(struct pthread_st, pt_state), thread->addr + offsetof(struct pthread_st, pt_state),
&tmp, sizeof(int))) != 0) &tmp, sizeof(tmp))) != 0)
return val; return val;
switch (tmp) { switch (tmp) {
case PT_STATE_RUNNING: case PT_STATE_RUNNING:
@ -226,7 +226,7 @@ td_thr_info(td_thread_t *thread, td_thread_info_t *info)
if ((val = READ(thread->proc, if ((val = READ(thread->proc,
thread->addr + offsetof(struct pthread_st, pt_type), thread->addr + offsetof(struct pthread_st, pt_type),
&tmp, sizeof(int))) != 0) &tmp, sizeof(tmp))) != 0)
return val; return val;
switch (tmp) { switch (tmp) {
case PT_THREAD_NORMAL: case PT_THREAD_NORMAL:
@ -247,7 +247,7 @@ td_thr_info(td_thread_t *thread, td_thread_info_t *info)
if ((val = READ(thread->proc, if ((val = READ(thread->proc,
thread->addr + offsetof(struct pthread_st, pt_joiners), thread->addr + offsetof(struct pthread_st, pt_joiners),
&queue, sizeof(struct pthread_queue_t))) != 0) &queue, sizeof(queue))) != 0)
return val; return val;
if (PTQ_EMPTY(&queue)) if (PTQ_EMPTY(&queue))
@ -262,7 +262,7 @@ td_thr_info(td_thread_t *thread, td_thread_info_t *info)
if ((val = READ(thread->proc, if ((val = READ(thread->proc,
thread->addr + offsetof(struct pthread_st, pt_num), thread->addr + offsetof(struct pthread_st, pt_num),
&info->thread_id, sizeof(info->thread_errno))) != 0) &info->thread_id, sizeof(info->thread_id))) != 0)
return val; return val;
if ((val = READ(thread->proc, if ((val = READ(thread->proc,
@ -315,7 +315,7 @@ td_thr_getregs(td_thread_t *thread, int regset, void *buf)
val = READ(thread->proc, val = READ(thread->proc,
thread->addr + offsetof(struct pthread_st, pt_state), thread->addr + offsetof(struct pthread_st, pt_state),
&tmp, sizeof(int)); &tmp, sizeof(tmp));
if (val != 0) if (val != 0)
return val; return val;
@ -375,7 +375,7 @@ td_thr_setregs(td_thread_t *thread, int regset, void *buf)
val = READ(thread->proc, val = READ(thread->proc,
thread->addr + offsetof(struct pthread_st, pt_state), thread->addr + offsetof(struct pthread_st, pt_state),
&tmp, sizeof(int)); &tmp, sizeof(tmp));
if (val != 0) if (val != 0)
return val; return val;
@ -447,7 +447,7 @@ td_thr_join_iter(td_thread_t *thread, int (*call)(td_thread_t *, void *),
if ((val = READ(thread->proc, if ((val = READ(thread->proc,
thread->addr + offsetof(struct pthread_st, pt_joiners), thread->addr + offsetof(struct pthread_st, pt_joiners),
&queue, sizeof(struct pthread_queue_t))) != 0) &queue, sizeof(queue))) != 0)
return val; return val;
next = (void *)queue.ptqh_first; next = (void *)queue.ptqh_first;
@ -490,7 +490,7 @@ td_sync_info(td_sync_t *s, td_sync_info_t *info)
info->sync_size = sizeof(struct pthread_mutex_st); info->sync_size = sizeof(struct pthread_mutex_st);
if ((val = READ(s->proc, if ((val = READ(s->proc,
s->addr + offsetof(struct pthread_mutex_st, ptm_blocked), s->addr + offsetof(struct pthread_mutex_st, ptm_blocked),
&queue, sizeof(struct pthread_queue_t))) != 0) &queue, sizeof(queue))) != 0)
return val; return val;
if (!PTQ_EMPTY(&queue)) if (!PTQ_EMPTY(&queue))
@ -502,14 +502,14 @@ td_sync_info(td_sync_t *s, td_sync_info_t *info)
*/ */
if ((val = READ(s->proc, if ((val = READ(s->proc,
s->addr + offsetof(struct pthread_mutex_st, ptm_lock), s->addr + offsetof(struct pthread_mutex_st, ptm_lock),
(void *)&slock, sizeof(struct pthread_spinlock_st))) != 0) (void *)&slock, sizeof(slock))) != 0)
return val; return val;
if (slock == __SIMPLELOCK_LOCKED) { if (slock == __SIMPLELOCK_LOCKED) {
info->sync_data.mutex.locked = 1; info->sync_data.mutex.locked = 1;
if ((val = READ(s->proc, if ((val = READ(s->proc,
s->addr + offsetof(struct pthread_mutex_st, s->addr + offsetof(struct pthread_mutex_st,
ptm_owner), ptm_owner),
&taddr, sizeof(pthread_t))) != 0) &taddr, sizeof(taddr))) != 0)
return val; return val;
taddr = pthread__id(taddr); taddr = pthread__id(taddr);
td__getthread(s->proc, (void *)taddr, td__getthread(s->proc, (void *)taddr,
@ -522,7 +522,7 @@ td_sync_info(td_sync_t *s, td_sync_info_t *info)
info->sync_size = sizeof(struct pthread_cond_st); info->sync_size = sizeof(struct pthread_cond_st);
if ((val = READ(s->proc, if ((val = READ(s->proc,
s->addr + offsetof(struct pthread_cond_st, ptc_waiters), s->addr + offsetof(struct pthread_cond_st, ptc_waiters),
&queue, sizeof(struct pthread_queue_t))) != 0) &queue, sizeof(queue))) != 0)
return val; return val;
if (!PTQ_EMPTY(&queue)) if (!PTQ_EMPTY(&queue))
info->sync_haswaiters = 1; info->sync_haswaiters = 1;
@ -532,7 +532,7 @@ td_sync_info(td_sync_t *s, td_sync_info_t *info)
info->sync_size = sizeof(struct pthread_spinlock_st); info->sync_size = sizeof(struct pthread_spinlock_st);
if ((val = READ(s->proc, if ((val = READ(s->proc,
s->addr + offsetof(struct pthread_spinlock_st, pts_spin), s->addr + offsetof(struct pthread_spinlock_st, pts_spin),
(void *)&slock, sizeof(struct pthread_spinlock_st))) != 0) (void *)&slock, sizeof(slock))) != 0)
return val; return val;
if (slock == __SIMPLELOCK_LOCKED) if (slock == __SIMPLELOCK_LOCKED)
info->sync_data.spin.locked = 1; info->sync_data.spin.locked = 1;
@ -544,7 +544,7 @@ td_sync_info(td_sync_t *s, td_sync_info_t *info)
&info->sync_data.join.thread); &info->sync_data.join.thread);
if ((val = READ(s->proc, if ((val = READ(s->proc,
s->addr + offsetof(struct pthread_st, pt_joiners), s->addr + offsetof(struct pthread_st, pt_joiners),
&queue, sizeof(struct pthread_queue_t))) != 0) &queue, sizeof(queue))) != 0)
return val; return val;
if (!PTQ_EMPTY(&queue)) if (!PTQ_EMPTY(&queue))
@ -555,14 +555,14 @@ td_sync_info(td_sync_t *s, td_sync_info_t *info)
info->sync_size = sizeof(struct pthread_rwlock_st); info->sync_size = sizeof(struct pthread_rwlock_st);
if ((val = READ(s->proc, if ((val = READ(s->proc,
s->addr + offsetof(struct pthread_rwlock_st, ptr_rblocked), s->addr + offsetof(struct pthread_rwlock_st, ptr_rblocked),
&queue, sizeof(struct pthread_queue_t))) != 0) &queue, sizeof(queue))) != 0)
return val; return val;
if (!PTQ_EMPTY(&queue)) if (!PTQ_EMPTY(&queue))
info->sync_haswaiters = 1; info->sync_haswaiters = 1;
if ((val = READ(s->proc, if ((val = READ(s->proc,
s->addr + offsetof(struct pthread_rwlock_st, ptr_wblocked), s->addr + offsetof(struct pthread_rwlock_st, ptr_wblocked),
&queue, sizeof(struct pthread_queue_t))) != 0) &queue, sizeof(queue))) != 0)
return val; return val;
if (!PTQ_EMPTY(&queue)) if (!PTQ_EMPTY(&queue))
info->sync_haswaiters = 1; info->sync_haswaiters = 1;
@ -571,7 +571,7 @@ td_sync_info(td_sync_t *s, td_sync_info_t *info)
info->sync_data.rwlock.locked = 0; info->sync_data.rwlock.locked = 0;
if ((val = READ(s->proc, if ((val = READ(s->proc,
s->addr + offsetof(struct pthread_rwlock_st, ptr_nreaders), s->addr + offsetof(struct pthread_rwlock_st, ptr_nreaders),
&n, sizeof(int))) != 0) &n, sizeof(n))) != 0)
return val; return val;
info->sync_data.rwlock.readlocks = n; info->sync_data.rwlock.readlocks = n;
if (n > 0) if (n > 0)
@ -579,7 +579,7 @@ td_sync_info(td_sync_t *s, td_sync_info_t *info)
if ((val = READ(s->proc, if ((val = READ(s->proc,
s->addr + offsetof(struct pthread_rwlock_st, ptr_writer), s->addr + offsetof(struct pthread_rwlock_st, ptr_writer),
&taddr, sizeof(pthread_t))) != 0) &taddr, sizeof(taddr))) != 0)
return val; return val;
if (taddr != 0) { if (taddr != 0) {
info->sync_data.rwlock.locked = 1; info->sync_data.rwlock.locked = 1;
@ -614,20 +614,20 @@ td_sync_waiters_iter(td_sync_t *s, int (*call)(td_thread_t *, void *),
case _PT_MUTEX_MAGIC: case _PT_MUTEX_MAGIC:
if ((val = READ(s->proc, if ((val = READ(s->proc,
s->addr + offsetof(struct pthread_mutex_st, ptm_blocked), s->addr + offsetof(struct pthread_mutex_st, ptm_blocked),
&queue, sizeof(struct pthread_queue_t))) != 0) &queue, sizeof(queue))) != 0)
return val; return val;
break; break;
case _PT_COND_MAGIC: case _PT_COND_MAGIC:
if ((val = READ(s->proc, if ((val = READ(s->proc,
s->addr + offsetof(struct pthread_cond_st, ptc_waiters), s->addr + offsetof(struct pthread_cond_st, ptc_waiters),
&queue, sizeof(struct pthread_queue_t))) != 0) &queue, sizeof(queue))) != 0)
return val; return val;
break; break;
case PT_MAGIC: case PT_MAGIC:
/* Redundant with join_iter, but what the hell... */ /* Redundant with join_iter, but what the hell... */
if ((val = READ(s->proc, if ((val = READ(s->proc,
s->addr + offsetof(struct pthread_st, pt_joiners), s->addr + offsetof(struct pthread_st, pt_joiners),
&queue, sizeof(struct pthread_queue_t))) != 0) &queue, sizeof(queue))) != 0)
return val; return val;
break; break;
default: default:
@ -789,7 +789,7 @@ td_map_lwps(td_proc_t *proc)
if (val != 0) if (val != 0)
return val; return val;
val = READ(proc, addr, &nlwps, sizeof(int)); val = READ(proc, addr, &nlwps, sizeof(nlwps));
if (val != 0) if (val != 0)
return val; return val;
@ -823,7 +823,7 @@ td_tsd_iter(td_proc_t *proc,
for (i = 0; i < PTHREAD_KEYS_MAX; i++) { for (i = 0; i < PTHREAD_KEYS_MAX; i++) {
val = READ(proc, allocaddr + i * sizeof(int), val = READ(proc, allocaddr + i * sizeof(int),
&allocated, sizeof(int)); &allocated, sizeof(allocated));
if (val != 0) if (val != 0)
return val; return val;
@ -851,7 +851,7 @@ td_thr_sleepinfo(td_thread_t *thread, td_sync_t **s)
if ((val = READ(thread->proc, if ((val = READ(thread->proc,
thread->addr + offsetof(struct pthread_st, pt_sleepobj), thread->addr + offsetof(struct pthread_st, pt_sleepobj),
&addr, sizeof(caddr_t))) != 0) &addr, sizeof(addr))) != 0)
return val; return val;
td__getsync(thread->proc, addr, s); td__getsync(thread->proc, addr, s);
@ -924,7 +924,7 @@ td_thr_tsd(td_thread_t *thread, pthread_key_t key, void **value)
val = READ(thread->proc, thread->addr + val = READ(thread->proc, thread->addr +
offsetof(struct pthread_st, pt_specific) + offsetof(struct pthread_st, pt_specific) +
key * sizeof(void *), &value, sizeof(void *)); key * sizeof(void *), value, sizeof(*value));
return val; return val;
} }