Changeset 1201
- Timestamp:
- 05/22/08 14:18:19 (16 years ago)
- Files:
-
- branches/libffado-2.0/src/debugmodule/debugmodule.cpp (modified) (6 diffs)
- branches/libffado-2.0/src/debugmodule/debugmodule.h (modified) (2 diffs)
- branches/libffado-2.0/src/libcontrol/Element.cpp (modified) (8 diffs)
- branches/libffado-2.0/src/libcontrol/Element.h (modified) (2 diffs)
- branches/libffado-2.0/src/libutil/PosixMutex.cpp (modified) (4 diffs)
- branches/libffado-2.0/support/dbus/controlserver.cpp (modified) (5 diffs)
- branches/libffado-2.0/support/dbus/ffado-dbus-server.cpp (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
branches/libffado-2.0/src/debugmodule/debugmodule.cpp
r1188 r1201 32 32 33 33 #include <time.h> 34 #include <execinfo.h> 34 35 #if DEBUG_BACKTRACE_SUPPORT 36 #include <execinfo.h> 37 #include <cxxabi.h> 38 #define GNU_SOURCE 39 #include <dlfcn.h> 40 #endif 35 41 36 42 #if DEBUG_USE_MESSAGE_BUFFER … … 288 294 perror("backtrace_symbols"); 289 295 } else { 296 char* outbuf = NULL; 297 size_t length; 298 int status; 299 Dl_info info; 290 300 for (int j = 0; j < m_backtrace_buffer_nb_seen; j++) { 291 fprintf(stderr, " %p => %s\n", m_backtrace_buffer_seen[j], strings[j]); 301 if (dladdr(m_backtrace_buffer_seen[j], &info) != 0) { 302 outbuf = __cxxabiv1::__cxa_demangle(info.dli_sname, outbuf, &length, &status); 303 if(outbuf && status == 0) { 304 fprintf(stderr, " %p => %s\n", 305 m_backtrace_buffer_seen[j], outbuf); 306 free(outbuf); 307 outbuf = NULL; 308 } else { 309 fprintf(stderr, " %p => %s (demangle status: %d)\n", 310 m_backtrace_buffer_seen[j], strings[j], status); 311 } 312 } else { 313 fprintf(stderr, " %p => %s\n", 314 m_backtrace_buffer_seen[j], strings[j]); 315 } 292 316 } 293 317 free(strings); … … 646 670 647 671 for (int j = 0; j < nptrs; j++) { 648 chars_written += snprintf(m_backtrace_strbuffer + chars_written, MB_BUFFERSIZE-chars_written, "%p ", m_backtrace_buffer[j]); 672 char name[64]; 673 name[0]=0; 674 getFunctionName(m_backtrace_buffer[j], name, 64); 675 chars_written += snprintf(m_backtrace_strbuffer + chars_written, MB_BUFFERSIZE-chars_written, "%s ", name); 649 676 } 650 677 chars_written += snprintf(m_backtrace_strbuffer + chars_written, MB_BUFFERSIZE-chars_written, "\n"); … … 660 687 seen = false; 661 688 int j; 662 for (j=0; j<m_backtrace_buffer_nb_seen & j < DEBUG_MAX_BACKTRACE_FUNCTIONS_SEEN; j++) {689 for (j=0; j<m_backtrace_buffer_nb_seen && j < DEBUG_MAX_BACKTRACE_FUNCTIONS_SEEN; j++) { 663 690 if(m_backtrace_buffer_seen[j] == m_backtrace_buffer[i]) { 664 691 seen = true; … … 666 693 } 667 694 } 668 if (!seen) { 695 if (!seen 696 && j < DEBUG_MAX_BACKTRACE_FUNCTIONS_SEEN) { 669 697 m_backtrace_buffer_seen[j] = m_backtrace_buffer[i]; 670 698 m_backtrace_buffer_nb_seen++; 671 699 } 672 700 } 673 701 674 702 print(m_backtrace_strbuffer); 675 703 … … 689 717 pthread_mutex_lock(&m_backtrace_lock); 690 718 nptrs = backtrace(m_backtrace_buffer, id+1); 691 if(id<nptrs) { 692 retval = m_backtrace_buffer[id]; 719 if(id >= nptrs) { 720 id = nptrs-1; 721 } 722 retval = m_backtrace_buffer[id]; 723 // save the pointers to the pointers-seen list such that we can 724 // dump their info later on 725 bool seen = false; 726 int j; 727 for (j=0; j<m_backtrace_buffer_nb_seen && j < DEBUG_MAX_BACKTRACE_FUNCTIONS_SEEN; j++) { 728 if(m_backtrace_buffer_seen[j] == m_backtrace_buffer[id]) { 729 seen = true; 730 break; 731 } 732 } 733 if (!seen 734 && j < DEBUG_MAX_BACKTRACE_FUNCTIONS_SEEN) { 735 m_backtrace_buffer_seen[j] = m_backtrace_buffer[id]; 736 m_backtrace_buffer_nb_seen++; 693 737 } 694 738 pthread_mutex_unlock(&m_backtrace_lock); 695 739 696 740 return retval; 697 741 } 742 743 void 744 DebugModuleManager::getFunctionName(void *ptr, char *buff, int len) 745 { 746 char* outbuf = NULL; 747 size_t length; 748 int status; 749 Dl_info info; 750 if (dladdr(ptr, &info) != 0) { 751 outbuf = abi::__cxa_demangle(info.dli_sname, outbuf, &length, &status); 752 if(outbuf && status == 0) { 753 if(len < (int)length) { 754 strncpy(buff, outbuf, len); 755 } else { 756 strncpy(buff, outbuf, length); 757 } 758 } else { 759 snprintf(buff, len, "%p (%s)", ptr, info.dli_sname); 760 } 761 } else { 762 snprintf(buff, len, "%p (I-ERR)", ptr); 763 } 764 if (outbuf) free(outbuf); 765 } 766 698 767 #endif 699 768 branches/libffado-2.0/src/debugmodule/debugmodule.h
r1157 r1201 252 252 #define debugBacktraceGet( _ID_ ) \ 253 253 DebugModuleManager::instance()->getBacktracePtr( _ID_ ); 254 #define debugGetFunctionNameFromAddr( _ADDR_, _BUFF_, _MAX_SIZE_ ) \ 255 DebugModuleManager::instance()->getFunctionName( _ADDR_, _BUFF_, _MAX_SIZE_ ); 254 256 #else 255 257 #define debugPrintBacktrace( _SIZE_ ) 256 258 #define debugBacktraceGet( _ID_ ) NULL 259 #define debugGetFunctionNameFromAddr( _ADDR_, _BUFF_, _MAX_SIZE_ ) 257 260 #endif 258 261 … … 336 339 void printBacktrace(int len); 337 340 void *getBacktracePtr(int id); 341 void getFunctionName( void *, char *, int ); 338 342 #endif 339 343 branches/libffado-2.0/src/libcontrol/Element.cpp
r1163 r1201 77 77 Element::lockControl() 78 78 { 79 if(!m_parent) { 80 debugOutput( DEBUG_LEVEL_VERBOSE, "Locking tree...\n"); 81 } 79 82 getLock().Lock(); 80 83 } … … 83 86 Element::unlockControl() 84 87 { 88 if(!m_parent) { 89 debugOutput( DEBUG_LEVEL_VERBOSE, "Unlocking tree...\n"); 90 } 85 91 getLock().Unlock(); 86 92 } … … 175 181 Container::getElementVector() 176 182 { 177 lockControl(); 183 if(!getLock().isLocked()) { 184 debugWarning("called on unlocked tree!\n"); 185 } 178 186 return m_Children; 179 }180 181 void182 Container::releaseElementVector()183 {184 unlockControl();185 187 } 186 188 … … 217 219 218 220 bool 219 Container::deleteElement(Element *e) 220 { 221 Util::MutexLockHelper lock(getLock()); 221 Container::deleteElementNoLock(Element *e) 222 { 222 223 if(e == NULL) return false; 223 224 debugOutput( DEBUG_LEVEL_VERBOSE, "Deleting Element %s from %s\n", … … 230 231 if(*it == e) { 231 232 m_Children.erase(it); 232 // unlock before emitting the signal233 lock.earlyUnlock();234 emitSignal(eS_Updated, m_Children.size());235 233 return true; 236 234 } … … 242 240 243 241 bool 242 Container::deleteElement(Element *e) 243 { 244 bool retval; 245 Util::MutexLockHelper lock(getLock()); 246 retval = deleteElementNoLock(e); 247 if(retval) { 248 // unlock before emitting the signal 249 lock.earlyUnlock(); 250 emitSignal(eS_Updated, m_Children.size()); 251 } 252 return retval; 253 } 254 255 bool 244 256 Container::clearElements(bool delete_pointers) 245 257 { … … 247 259 while(m_Children.size()) { 248 260 Element *e=m_Children[0]; 249 deleteElement (e);261 deleteElementNoLock(e); 250 262 if (delete_pointers) delete e; 251 263 } … … 275 287 Container::setVerboseLevel(int l) 276 288 { 277 Util::MutexLockHelper lock(getLock());278 289 setDebugLevel(l); 279 290 for ( ElementVectorIterator it = m_Children.begin(); branches/libffado-2.0/src/libcontrol/Element.h
r1163 r1201 150 150 151 151 /** 152 * Returns and locks the element vector. No changes will be made to the vector153 * until releaseElementVector is called.152 * Returns the element vector. be sure to lock the tree while using 153 * the return value. 154 154 * @return 155 155 */ 156 156 const ElementVector & getElementVector(); 157 158 /**159 * Releases the lock on the element vector.160 */161 void releaseElementVector();162 157 163 158 virtual void show(); … … 167 162 eS_Updated, 168 163 }; 164 165 private: 166 bool deleteElementNoLock(Element *e); 169 167 170 168 protected: branches/libffado-2.0/src/libutil/PosixMutex.cpp
r1184 r1201 33 33 // check whether backtracing is enabled 34 34 #if DEBUG_LOCK_COLLISION_TRACING 35 #define DEBUG_LOCK_COLLISION_TRACING_INDEX 2 36 #define DEBUG_LOCK_COLLISION_TRACING_NAME_MAXLEN 64 35 37 #if DEBUG_BACKTRACE_SUPPORT 36 38 // ok … … 70 72 PosixMutex::Lock() 71 73 { 74 int err; 72 75 debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE, "(%p) lock\n", this); 73 76 #if DEBUG_LOCK_COLLISION_TRACING 74 77 if(TryLock()) { 75 78 // locking succeeded 76 m_locked_by = debugBacktraceGet(1); 79 m_locked_by = debugBacktraceGet( DEBUG_LOCK_COLLISION_TRACING_INDEX ); 80 81 char name[ DEBUG_LOCK_COLLISION_TRACING_NAME_MAXLEN ]; 82 name[0] = 0; 83 debugGetFunctionNameFromAddr(m_locked_by, name, DEBUG_LOCK_COLLISION_TRACING_NAME_MAXLEN); 84 77 85 debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE, 78 "(%p) % p haslock\n",79 this, m_locked_by);86 "(%p) %s obtained lock\n", 87 this, name); 80 88 return; 81 89 } else { 82 void *lock_try_by = debugBacktraceGet(1); 83 debugOutput(DEBUG_LEVEL_VERBOSE, 84 "(%p) lock collision: %p wants lock, %p has lock\n", 85 this, lock_try_by, m_locked_by); 86 pthread_mutex_lock(&m_mutex); 90 void *lock_try_by = debugBacktraceGet( DEBUG_LOCK_COLLISION_TRACING_INDEX ); 91 92 char name1[ DEBUG_LOCK_COLLISION_TRACING_NAME_MAXLEN ]; 93 name1[0] = 0; 94 debugGetFunctionNameFromAddr(lock_try_by, name1, DEBUG_LOCK_COLLISION_TRACING_NAME_MAXLEN); 95 char name2[ DEBUG_LOCK_COLLISION_TRACING_NAME_MAXLEN ]; 96 name2[0] = 0; 97 debugGetFunctionNameFromAddr(m_locked_by, name2, DEBUG_LOCK_COLLISION_TRACING_NAME_MAXLEN); 98 99 debugWarning("(%p) lock collision: %s wants lock, %s has lock\n", 100 this, name1, name2); 101 if((err = pthread_mutex_lock(&m_mutex))) { 102 if (err == EDEADLK) { 103 debugError("Resource deadlock detected\n"); 104 debugPrintBacktrace(10); 105 } else { 106 debugError("Error locking the mutex: %d\n", err); 107 } 108 } else { 109 debugWarning("(%p) lock collision: %s got lock (from %s?)\n", 110 this, name1, name2); 111 } 112 } 113 #else 114 #ifdef DEBUG 115 if((err = pthread_mutex_lock(&m_mutex))) { 116 if (err == EDEADLK) { 117 debugError("Resource deadlock detected\n"); 118 debugPrintBacktrace(10); 119 } else { 120 debugError("Error locking the mutex: %d\n", err); 121 } 122 } else { 123 debugWarning("(%p) lock collision: %s got lock (from %s?)\n", 124 this, name1, name2); 87 125 } 88 126 #else 89 127 pthread_mutex_lock(&m_mutex); 128 #endif 90 129 #endif 91 130 } … … 121 160 // unlocking 122 161 m_locked_by = NULL; 123 void *unlocker = debugBacktraceGet(1); 162 void *unlocker = debugBacktraceGet( DEBUG_LOCK_COLLISION_TRACING_INDEX ); 163 char name[ DEBUG_LOCK_COLLISION_TRACING_NAME_MAXLEN ]; 164 name[0] = 0; 165 debugGetFunctionNameFromAddr(unlocker, name, DEBUG_LOCK_COLLISION_TRACING_NAME_MAXLEN); 124 166 debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE, 125 "(%p) % preleases lock\n",126 this, unlocker);167 "(%p) %s releases lock\n", 168 this, name); 127 169 #endif 128 170 171 #ifdef DEBUG 172 int err; 173 if((err = pthread_mutex_unlock(&m_mutex))) { 174 debugError("Error unlocking the mutex: %d\n", err); 175 } 176 #else 129 177 pthread_mutex_unlock(&m_mutex); 178 #endif 130 179 } 131 180 … … 133 182 PosixMutex::show() 134 183 { 135 debugOutput(DEBUG_LEVEL_NORMAL, "(%p) mutex \n", this);184 debugOutput(DEBUG_LEVEL_NORMAL, "(%p) mutex (%s)\n", this, (isLocked() ? "Locked" : "Unlocked")); 136 185 } 137 186 branches/libffado-2.0/support/dbus/controlserver.cpp
r1173 r1201 184 184 int nbElements=m_Slave.countElements(); 185 185 if (i<nbElements) { 186 m_Slave.lockControl(); 186 187 const Control::ElementVector elements = m_Slave.getElementVector(); 187 188 Control::Element *e = elements.at(i); 188 189 std::string name; 189 190 if(e) name = e->getName(); 190 m_Slave. releaseElementVector();191 m_Slave.unlockControl(); 191 192 return name; 192 193 } else return ""; … … 194 195 // Util::MutexLockHelper lock(*m_access_lock); 195 196 196 // NOTE: call with access lock held!197 // NOTE: call with tree locked 197 198 void 198 199 Container::updateTree() … … 263 264 to_remove.erase(to_remove.begin()); 264 265 } 265 m_Slave.releaseElementVector();266 266 267 267 if(something_changed) { … … 279 279 debugOutput(DEBUG_LEVEL_VERBOSE, 280 280 "removing handler %p on path %s\n", 281 path().c_str(), e);281 e, path().c_str()); 282 282 for ( ElementVectorIterator it = m_Children.begin(); 283 283 it != m_Children.end(); … … 313 313 // we lock the tree first 314 314 Lock(); 315 316 // also lock the slave tree 317 m_Slave.lockControl(); 318 315 319 // update our tree 316 320 updateTree(); 321 322 // now unlock the slave tree 323 m_Slave.unlockControl(); 324 325 // and unlock the access 317 326 Unlock(); 318 327 } branches/libffado-2.0/support/dbus/ffado-dbus-server.cpp
r1196 r1201 300 300 conn.request_name("org.ffado.Control"); 301 301 302 // lock the control tree such that it does not get modified while we build our view 303 m_deviceManager->lockControl(); 302 304 container = new DBusControl::Container(conn, "/org/ffado/Control/DeviceManager", 303 305 NULL, *m_deviceManager); 304 306 // unlock the control tree since the tree is built 307 m_deviceManager->unlockControl(); 308 305 309 printMessage("DBUS test service running\n"); 306 310 printMessage("press ctrl-c to stop it & exit\n"); … … 309 313 debugOutput( DEBUG_LEVEL_NORMAL, "dispatching...\n"); 310 314 dispatcher.enter(); 315 311 316 debugOutput( DEBUG_LEVEL_NORMAL, " dispatcher exited...\n"); 312 317 sem_wait(&run_sem);