aboutsummaryrefslogtreecommitdiffstats
path: root/main/utils.c
diff options
context:
space:
mode:
authormurf <murf@f38db490-d61c-443f-a65b-d21fe96a405b>2008-04-22 14:38:46 +0000
committermurf <murf@f38db490-d61c-443f-a65b-d21fe96a405b>2008-04-22 14:38:46 +0000
commit96cbd86b579add126ae27fd3bd0067f86d96151c (patch)
treeb984c3a887dd7968073113d0ae18215bf43c91dc /main/utils.c
parent11ee51ef7d28a6019c81983cfda30d09a9d1064f (diff)
Hopefully, this will resolve the issues that russellb had with this log_show_lock().
I gathered the code that filled the string, and put it in a different func which I cryptically call "append_lock_information()". Now, both log_show_lock(), and handle_show_locks() both call this code to do the work. Tested, seems to work fine. Also, log_show_lock was modified to use the ast_str stuff, along with checking for successful ast_str creation, and freeing the ast_str obj when finished. A break was inserted to terminate the search for the lock; we should never see it twice. An example usage in chan_sip.c was created as a comment, for instructional purposes. git-svn-id: http://svn.digium.com/svn/asterisk/trunk@114520 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'main/utils.c')
-rw-r--r--main/utils.c125
1 files changed, 66 insertions, 59 deletions
diff --git a/main/utils.c b/main/utils.c
index 3ae7d0927..a91e1062b 100644
--- a/main/utils.c
+++ b/main/utils.c
@@ -714,52 +714,86 @@ static const char *locktype2str(enum ast_lock_type type)
return "UNKNOWN";
}
-/*! \todo this function is very broken and duplicates a lot of code ... */
+static void append_lock_information(struct ast_str **str, struct thr_lock_info *lock_info, int i)
+{
+ int j;
+ ast_mutex_t *lock;
+
+ ast_str_append(str, 0, "=== ---> %sLock #%d (%s): %s %d %s %s %p (%d)\n",
+ lock_info->locks[i].pending > 0 ? "Waiting for " :
+ lock_info->locks[i].pending < 0 ? "Tried and failed to get " : "", i,
+ lock_info->locks[i].file,
+ locktype2str(lock_info->locks[i].type),
+ lock_info->locks[i].line_num,
+ lock_info->locks[i].func, lock_info->locks[i].lock_name,
+ lock_info->locks[i].lock_addr,
+ lock_info->locks[i].times_locked);
+
+ if (!lock_info->locks[i].pending || lock_info->locks[i].pending == -1)
+ return;
+
+ /* We only have further details for mutexes right now */
+ if (lock_info->locks[i].type != AST_MUTEX)
+ return;
+
+ lock = lock_info->locks[i].lock_addr;
+
+ ast_reentrancy_lock(lock);
+ for (j = 0; *str && j < lock->reentrancy; j++) {
+ ast_str_append(str, 0, "=== --- ---> Locked Here: %s line %d (%s)\n",
+ lock->file[j], lock->lineno[j], lock->func[j]);
+ }
+ ast_reentrancy_unlock(lock);
+}
+
+
+/*! This function can help you find highly temporal locks; locks that happen for a
+ short time, but at unexpected times, usually at times that create a deadlock,
+ Why is this thing locked right then? Who is locking it? Who am I fighting
+ with for this lock?
+
+ To answer such questions, just call this routine before you would normally try
+ to aquire a lock. It doesn't do anything if the lock is not acquired. If the
+ lock is taken, it will publish a line or two to the console via ast_log().
+
+ Sometimes, the lock message is pretty uninformative. For instance, you might
+ find that the lock is being aquired deep within the astobj2 code; this tells
+ you little about higher level routines that call the astobj2 routines.
+ But, using gdb, you can set a break at the ast_log below, and for that
+ breakpoint, you can set the commands:
+ where
+ cont
+ which will give a stack trace and continue. -- that aught to do the job!
+
+*/
void log_show_lock(void *this_lock_addr)
{
struct thr_lock_info *lock_info;
- struct ast_str *str = NULL;
+ struct ast_str *str;
+
+ if (!(str = ast_str_create(4096))) {
+ ast_log(LOG_NOTICE,"Could not create str\n");
+ return;
+ }
+
pthread_mutex_lock(&lock_infos_lock.mutex);
AST_LIST_TRAVERSE(&lock_infos, lock_info, entry) {
int i;
pthread_mutex_lock(&lock_info->lock);
for (i = 0; str && i < lock_info->num_locks; i++) {
- int j;
- ast_mutex_t *lock;
+ /* ONLY show info about this particular lock, if
+ it's acquired... */
if (lock_info->locks[i].lock_addr == this_lock_addr) {
-
- ast_log(LOG_NOTICE, "---> %sLock #%d (%s): %s %d %s %s %p (%d)\n",
- lock_info->locks[i].pending > 0 ? "Waiting for " : lock_info->locks[i].pending < 0 ? "Tried and failed to get " : "",
- i,
- lock_info->locks[i].file,
- locktype2str(lock_info->locks[i].type),
- lock_info->locks[i].line_num,
- lock_info->locks[i].func,
- lock_info->locks[i].lock_name,
- lock_info->locks[i].lock_addr,
- lock_info->locks[i].times_locked);
-
- if (!lock_info->locks[i].pending || lock_info->locks[i].pending == -1)
- continue;
-
- /* We only have further details for mutexes right now */
- if (lock_info->locks[i].type != AST_MUTEX)
- continue;
-
- lock = lock_info->locks[i].lock_addr;
-
- ast_reentrancy_lock(lock);
- for (j = 0; str && j < lock->reentrancy; j++) {
- ast_log(LOG_NOTICE, "--- ---> Locked Here: %s line %d (%s)\n",
- lock->file[j], lock->lineno[j], lock->func[j]);
- }
- ast_reentrancy_unlock(lock);
+ append_lock_information(&str, lock_info, i);
+ ast_log(LOG_NOTICE, "%s", str->str);
+ break;
}
}
pthread_mutex_unlock(&lock_info->lock);
}
pthread_mutex_unlock(&lock_infos_lock.mutex);
+ ast_free(str);
}
@@ -802,34 +836,7 @@ static char *handle_show_locks(struct ast_cli_entry *e, int cmd, struct ast_cli_
lock_info->thread_name);
pthread_mutex_lock(&lock_info->lock);
for (i = 0; str && i < lock_info->num_locks; i++) {
- int j;
- ast_mutex_t *lock;
-
- ast_str_append(&str, 0, "=== ---> %sLock #%d (%s): %s %d %s %s %p (%d)\n",
- lock_info->locks[i].pending > 0 ? "Waiting for " :
- lock_info->locks[i].pending < 0 ? "Tried and failed to get " : "", i,
- lock_info->locks[i].file,
- locktype2str(lock_info->locks[i].type),
- lock_info->locks[i].line_num,
- lock_info->locks[i].func, lock_info->locks[i].lock_name,
- lock_info->locks[i].lock_addr,
- lock_info->locks[i].times_locked);
-
- if (!lock_info->locks[i].pending || lock_info->locks[i].pending == -1)
- continue;
-
- /* We only have further details for mutexes right now */
- if (lock_info->locks[i].type != AST_MUTEX)
- continue;
-
- lock = lock_info->locks[i].lock_addr;
-
- ast_reentrancy_lock(lock);
- for (j = 0; str && j < lock->reentrancy; j++) {
- ast_str_append(&str, 0, "=== --- ---> Locked Here: %s line %d (%s)\n",
- lock->file[j], lock->lineno[j], lock->func[j]);
- }
- ast_reentrancy_unlock(lock);
+ append_lock_information(&str, lock_info, i);
}
pthread_mutex_unlock(&lock_info->lock);
if (!str)