srs.py 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. import gdb, traceback;
  2. '''
  3. Usage:
  4. nn_coroutines
  5. nn_coroutines 1000
  6. '''
  7. class NnCoroutines(gdb.Command):
  8. def __init__(self):
  9. super(NnCoroutines, self).__init__('nn_coroutines', gdb.COMMAND_DATA)
  10. # https://sourceware.org/gdb/current/onlinedocs/gdb/Python-API.html#Python-API
  11. def invoke(self, arg, from_tty):
  12. nn_interval=1000
  13. nn_coroutines = 1
  14. # Parse args.
  15. args = arg.split(' ')
  16. if args[0] != '':
  17. nn_interval = int(args[0])
  18. try:
  19. pnext = prev = pthis = gdb.parse_and_eval('&_st_this_thread->tlink').__str__()
  20. print('interval: %s, first: %s, args(%s): %s'%(nn_interval, pthis, len(args), args))
  21. while True:
  22. v = gdb.parse_and_eval('((_st_clist_t*)%s)->next'%pnext)
  23. prev = pnext = str(v.__str__()).split(' ')[0]
  24. if pnext == pthis:
  25. break
  26. nn_coroutines += 1
  27. if (nn_coroutines%nn_interval) == 0:
  28. print('next is %s, total %s'%(pnext, nn_coroutines))
  29. except:
  30. print('Error: prev=%s, this=%s, next=%s, v=%s'%(prev, pthis, pnext, v))
  31. traceback.print_exc()
  32. # Result.
  33. print('total coroutines: %s'%(nn_coroutines))
  34. NnCoroutines()
  35. '''
  36. Usage:
  37. show_coroutines
  38. '''
  39. class ShowCoroutines(gdb.Command):
  40. def __init__(self):
  41. super(ShowCoroutines, self).__init__('show_coroutines', gdb.COMMAND_DATA)
  42. # https://sourceware.org/gdb/current/onlinedocs/gdb/Python-API.html#Python-API
  43. def invoke(self, arg, from_tty):
  44. offset = gdb.parse_and_eval('(int)(&(((_st_thread_t*)(0))->tlink))').__str__()
  45. _st_this_thread = gdb.parse_and_eval('_st_this_thread').__str__()
  46. pnext = prev = pthis = gdb.parse_and_eval('&_st_this_thread->tlink').__str__()
  47. this_thread2 = gdb.parse_and_eval('(_st_thread_t*)(%s - %s)'%(pthis, offset)).__str__()
  48. #print('offset=%s, _st_this_thread=%s, pthis-offset=%s'%(offset, _st_this_thread, this_thread2))
  49. try:
  50. while True:
  51. trd = gdb.parse_and_eval('(_st_thread_t*)(%s - %s)'%(pnext, offset)).__str__()
  52. jmpbuf = gdb.parse_and_eval('((_st_thread_t*)%s)->context.__jmpbuf'%(trd)).__str__().split(', ')
  53. rbp, rsp, crip = int(jmpbuf[1]), int(jmpbuf[6]), None
  54. if rbp > 0 and rsp > 0:
  55. crip = gdb.execute('x/2xa %s'%(rbp), to_string=True).split('\t')[2].strip()
  56. print('thread: %s, caller: %s'%(trd, crip))
  57. v = gdb.parse_and_eval('((_st_clist_t*)%s)->next'%pnext)
  58. prev = pnext = str(v.__str__()).split(' ')[0]
  59. if pnext == pthis:
  60. break
  61. except:
  62. print('Error: prev=%s, this=%s, next=%s'%(prev, pthis, pnext))
  63. traceback.print_exc()
  64. ShowCoroutines()