etp-commands
来自「OTP是开放电信平台的简称」· 代码 · 共 1,993 行 · 第 1/4 页
TXT
1,993 行
# Reentrant capable# etp-mfa-1 ($arg0) 0 printf ".\n"enddocument etp-mfa%---------------------------------------------------------------------------% etp-mfa Eterm*% % Take an Eterm* to an MFA function name entry and print it.% These can be found e.g in the process structure;% process_tab[i]->current and process_tab[i]->initial.%---------------------------------------------------------------------------enddefine etp-cp-1# Args: Eterm cp## Non-reentrant# set $etp_cp = (Eterm)($arg0) set $etp_cp_low = modules set $etp_cp_high = $etp_cp_low + num_loaded_modules set $etp_cp_mid = mid_module set $etp_cp_p = 0 # while $etp_cp_low < $etp_cp_high if $etp_cp < $etp_cp_mid->start set $etp_cp_high = $etp_cp_mid else if $etp_cp > $etp_cp_mid->end set $etp_cp_low = $etp_cp_mid + 1 else set $etp_cp_p = $etp_cp_low = $etp_cp_high = $etp_cp_mid end end set $etp_cp_mid = $etp_cp_low + ($etp_cp_high-$etp_cp_low)/2 end if $etp_cp_p set $etp_cp_low = (Eterm**)($etp_cp_p->start + 8) set $etp_cp_high = $etp_cp_low +$etp_cp_p->start[0] set $etp_cp_p = 0 while $etp_cp_low < $etp_cp_high set $etp_cp_mid = $etp_cp_low + ($etp_cp_high-$etp_cp_low)/2 if $etp_cp < $etp_cp_mid[0] set $etp_cp_high = $etp_cp_mid else if $etp_cp < $etp_cp_mid[1] set $etp_cp_p = $etp_cp_mid[0]+2 set $etp_cp_low = $etp_cp_high = $etp_cp_mid else set $etp_cp_low = $etp_cp_mid + 1 end end end end if $etp_cp_p printf "#Cp" etp-mfa-1 ($etp_cp_p) ($etp_cp-((Eterm)($etp_cp_p-2))) else if $etp_cp == beam_apply+1 printf "#Cp<terminate process normally>" else if *(Eterm*)($etp_cp) == beam_return_trace[0] if ($etp_cp) == beam_exception_trace printf "#Cp<exception trace>" else printf "#Cp<return trace>" end else if *(Eterm*)($etp_cp) == beam_return_to_trace[0] printf "#Cp<return to trace>" else printf "#Cp<%#x>", $etp_cp end end end endenddefine etp-cp# Args: Eterm cp## Reentrant capable# etp-cp-1 ($arg0) printf ".\n"enddocument etp-cp%---------------------------------------------------------------------------% etp-cp Eterm% % Take a code continuation pointer and print % module, function, arity and offset. % % Code continuation pointers can be found in the process structure e.g% process_tab[i]->cp and process_tab[i]->i, the second is the% program counter, which is the same thing as a continuation pointer.%---------------------------------------------------------------------------end############################################################################# Commands for special term bunches.#define etp-msgq# Args: ErlMessageQueue*## Non-reentrant# set $etp_msgq = ($arg0) set $etp_msgq_p = $etp_msgq->first set $etp_msgq_i = $etp_msgq->len set $etp_msgq_prev = $etp_msgq->last printf "%% Message queue (%d):", $etp_msgq_i if ($etp_msgq_i > 0) && $etp_msgq_p printf "\n[" else printf "\n" end while ($etp_msgq_i > 0) && $etp_msgq_p set $etp_msgq_i-- set $etp_msgq_next = $etp_msgq_p->next # Msg etp-1 ($etp_msgq_p->m[0]) 0 if ($etp_msgq_i > 0) && $etp_msgq_next printf ", %% " else printf "]. %% " end # Seq_trace token etp-1 ($etp_msgq_p->m[1]) 0 if $etp_msgq_p == $etp_msgq->save printf ", <=\n" else printf "\n" end if ($etp_msgq_i > 0) && $etp_msgq_next printf " " end # set $etp_msgq_prev = $etp_msgq_p set $etp_msgq_p = $etp_msgq_next end if $etp_msgq_i != 0 printf "#MsgQShort<%d>\n", $etp_msgq_i end if $etp_msgq_p != 0 printf "#MsgQLong<%#lx%p>\n", (unsigned long)$etp_msgq_p end if $etp_msgq_prev != $etp_msgq->last printf "#MsgQEndError<%#lx%p>\n", (unsigned long)$etp_msgq_prev endenddocument etp-msgq%---------------------------------------------------------------------------% etp-msgq ErlMessageQueue*% % Take an ErlMessageQueue* and print the contents of the message queue. % Sequential trace tokens are included in comments and % the current match position in the queue is marked '<='.% % A process's message queue is process_tab[i]->msg.%---------------------------------------------------------------------------enddefine etpf-msgq# Args: Process*## Non-reentrant# set $etp_flat = 1 etp-msgq ($arg0) set $etp_flat = 0enddocument etpf-msgq%---------------------------------------------------------------------------% etpf-msgq ErlMessageQueue*% % Same as 'etp-msgq' but print the messages using etpf (flat).%---------------------------------------------------------------------------enddefine etp-stacktrace# Args: Process*## Non-reentrant# set $etp_stacktrace_p = ($arg0)->stop set $etp_stacktrace_end = ($arg0)->hend printf "%% Stacktrace (%u): ", $etp_stacktrace_end-$etp_stacktrace_p etp ($arg0)->cp while $etp_stacktrace_p < $etp_stacktrace_end if ($etp_stacktrace_p[0] & 0x3) == 0x0 # Continuation pointer etp $etp_stacktrace_p[0] end set $etp_stacktrace_p++ endenddocument etp-stacktrace%---------------------------------------------------------------------------% etp-stacktrace Process*% % Take an Process* and print a stactrace for the process.% The stacktrace consists just of the pushed code continuation% pointers on the stack, the most recently pushed first.%---------------------------------------------------------------------------enddefine etp-stackdump# Args: Process*## Non-reentrant# set $etp_stackdump_p = ($arg0)->stop set $etp_stackdump_end = ($arg0)->hend printf "%% Stackdump (%u): ", $etp_stackdump_end-$etp_stackdump_p etp ($arg0)->cp while $etp_stackdump_p < $etp_stackdump_end etp $etp_stackdump_p[0] set $etp_stackdump_p++ endenddocument etp-stackdump%---------------------------------------------------------------------------% etp-stackdump Process*% % Take an Process* and print a stackdump for the process.% The stackdump consists of all pushed values on the stack.% All code continuation pointers are preceeded with a line% of dashes to make the stack frames more visible.%---------------------------------------------------------------------------enddefine etpf-stackdump# Args: Process*## Non-reentrant# set $etp_flat = 1 etp-stackdump ($arg0) set $etp_flat = 0enddocument etpf-stackdump%---------------------------------------------------------------------------% etpf-stackdump Process*% % Same as etp-stackdump but print the values using etpf (flat).%---------------------------------------------------------------------------enddefine etp-dictdump# Args: ProcDict*## Non-reentrant# set $etp_dictdump = ($arg0) if $etp_dictdump set $etp_dictdump_n = \ $etp_dictdump->homeSize + $etp_dictdump->splitPosition set $etp_dictdump_i = 0 set $etp_dictdump_written = 0 if $etp_dictdump_n > $etp_dictdump->size set $etp_dictdump_n = $etp_dictdump->size end set $etp_dictdump_cnt = $etp_dictdump->numElements printf "%% Dictionary (%d):\n[", $etp_dictdump_cnt while $etp_dictdump_i < $etp_dictdump_n && \ $etp_dictdump_cnt > 0 set $etp_dictdump_p = $etp_dictdump->data[$etp_dictdump_i] if $etp_dictdump_p != $etp_nil if ((Eterm)$etp_dictdump_p & 0x3) == 0x2 # Boxed if $etp_dictdump_written printf ",\n " else set $etp_dictdump_written = 1 end etp-1 $etp_dictdump_p 0 set $etp_dictdump_cnt-- else while ((Eterm)$etp_dictdump_p & 0x3) == 0x1 && \ $etp_dictdump_cnt > 0 # Cons ptr if $etp_dictdump_written printf ",\n " else set $etp_dictdump_written = 1 end etp-1 (((Eterm*)((Eterm)$etp_dictdump_p&~0x3))[0]) 0 set $etp_dictdump_cnt-- set $etp_dictdump_p = ((Eterm*)((Eterm)$etp_dictdump_p & ~0x3))[1] end if $etp_dictdump_p != $etp_nil printf "#DictSlotError<%d>:", $etp_dictdump_i set $etp_dictdump_flat = $etp_flat set $etp_flat = 1 etp-1 ((Eterm)$etp_dictdump_p) 0 set $etp_flat = $etp_dictdump_flat end end end set $etp_dictdump_i++ end if $etp_dictdump_cnt != 0 printf "#DictCntError<%d>, ", $etp_dictdump_cnt end else printf "%% Dictionary (0):\n[" end printf "].\n"enddocument etp-dictdump%---------------------------------------------------------------------------% etp-dictdump ErlProcDict*% % Take an ErlProcDict* and print all entries in the process dictionary.%---------------------------------------------------------------------------enddefine etpf-dictdump# Args: ErlProcDict*## Non-reentrant# set $etp_flat = 1 etp-dictdump ($arg0) set $etp_flat = 0enddocument etpf-dictdump%---------------------------------------------------------------------------% etpf-dictdump ErlProcDict*% % Same as etp-dictdump but print the values using etpf (flat).%---------------------------------------------------------------------------enddefine etp-offheapdump# Args: ( ExternalThing* | ProcBin* | ErlFunThing* )## Non-reentrant# set $etp_offheapdump_p = ($arg0) set $etp_offheapdump_i = 0 set $etp_offheapdump_ printf "%% Offheap dump:\n[" while ($etp_offheapdump_p != 0) && ($etp_offheapdump_i < $etp_max_depth) if ((Eterm)$etp_offheapdump_p & 0x3) == 0x0 if $etp_offheapdump_i > 0 printf ",\n " end etp-1 ((Eterm)$etp_offheapdump_p|0x2) 0 set $etp_offheapdump_p = $etp_offheapdump_p->next set $etp_offheapdump_i++ else printf "#TaggedPtr<%#x>", $etp_offheapdump_p set $etp_offheapdump_p = 0 end end printf "].\n"enddocument etp-offheapdump%---------------------------------------------------------------------------% etp-offheapdump ( ExternalThing* | ProcBin* | ErlFunThing* )% % Take an pointer to a linked list and print the terms in the list% up to the max depth.%---------------------------------------------------------------------------enddefine etpf-offheapdump# Args: ( ExternalThing* | ProcBin* | ErlFunThing* )## Non-reentrant# set $etp_flat = 1 etp-offheapdump ($arg0) set $etp_flat = 0enddocument etpf-offheapdump%---------------------------------------------------------------------------% etpf-offheapdump ( ExternalThing* | ProcBin* | ErlFunThing* )% % Same as etp-offheapdump but print the values using etpf (flat).%---------------------------------------------------------------------------enddefine etp-search-heaps# Args: Eterm## Non-reentrant# printf "%% Search all (<%u) process heaps for ", erts_max_processes set $etp_flat = 1 etp-1 ($arg0) 0 set $etp_flat = 0 printf ":...\n" etp-search-heaps-1 ((Eterm*)((Eterm)($arg0)&~3))enddefine etp-search-heaps-1# Args: Eterm*## Non-reentrant# set $etp_search_heaps_q = erts_max_processes / 10 set $etp_search_heaps_r = erts_max_processes % 10 set $etp_search_heaps_t = 10 set $etp_search_heaps_m = $etp_search_heaps_q if $etp_search_heaps_r > 0 set $etp_search_heaps_m++ set $etp_search_heaps_r-- end set $etp_search_heaps_i = 0 set $etp_search_heaps_found = 0 while $etp_search_heaps_i < erts_max_processes if process_tab[$etp_search_heaps_i] if (process_tab[$etp_search_heaps_i]->heap <= ($arg0)) && \ (($arg0) < process_tab[$etp_search_heaps_i]->hend) printf "process_tab[%d]->heap+%d\n", $etp_search_heaps_i, \ ($arg0)-process_tab[$etp_search_heaps_i]->heap end if (process_tab[$etp_search_heaps_i]->old_heap <= ($arg0)) && \ (($arg0) <= process_tab[$etp_search_heaps_i]->old_hend) printf "process_tab[%d]->old_heap+%d\n", $etp_search_heaps_i, \ ($arg0)-process_tab[$etp_search_heaps_i]->old_heap end set $etp_search_heaps_cnt = 0 set $etp_search_heaps_p = process_tab[$etp_search_heaps_i]->mbuf while $etp_search_heaps_p && ($etp_search_heaps_cnt < $etp_max_depth) set $etp_search_heaps_cnt++ if (&($etp_search_heaps_p->mem) <= ($arg0)) && \ (($arg0) < &($etp_search_heaps_p->mem)+$etp_search_heaps_p->size) printf "process_tab[%d]->mbuf(%d)+%d\n", \ $etp_search_heaps_i, $etp_search_heaps_cnt, \ ($arg0)-&($etp_search_heaps_p->mem) end set $etp_search_heaps_p = $etp_search_heaps_p->next end if $etp_search_heaps_p printf "process_tab[%d] %% Too many HeapFragments\n", \ $etp_search_heaps_i end end set $etp_search_heaps_i++ if $etp_search_heaps_i > $etp_search_heaps_m printf "%% %d%%...\n", $etp_search_heaps_t set $etp_search_heaps_t += 10 set $etp_search_heaps_m += $etp_search_heaps_q if $etp_search_heaps_r > 0 set $etp_search_heaps_m++ set $etp_search_heaps_r-- end end end printf "%% 100%%.\n"enddocument etp-search-heaps%---------------------------------------------------------------------------% etp-search-heaps Eterm% % Search all process heaps in process_tab[], including the heap fragments% (process_tab[]->mbuf) for the specified Eterm.%---------------------------------------------------------------------------enddefine etp-search-alloc# Args: Eterm## Non-reentrant# printf "%% Search allocated memory blocks for "
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?