Możesz zdobyć wszystkie atomy za pomocą nieudokumentowanej funkcji formatu terminu zewnętrznego.
Termin Erlanga zakodowany w formacie warunków zewnętrznych zaczyna się od bajtu 131, następnie bajtu identyfikującego typ, a następnie rzeczywistych danych. Zauważyłem, że EEP-43 wymienia wszystkie możliwe typy, w tym ATOM_INTERNAL_REF3
z bajtem typu 75, który nie jest wymieniony w official documentation of the external term format.
Dla ATOM_INTERNAL_REF3
dane są indeksem do tabeli atomów zakodowanymi jako 24-bitowa liczba całkowita. Możemy łatwo stworzyć taki plik binarny: <<131,75,N:24>>
Na przykład w moim Erlang VM false
wydaje się być atom zerowego w tabeli Atom:
> binary_to_term(<<131,75,0:24>>).
false
Nie ma prosty sposób na znalezienie liczbę atomów obecnie w tabeli atomów *, ale możemy ciągle zwiększać liczbę, dopóki nie otrzymamy błędu badarg
.
Więc ten mały moduł daje listę wszystkich atomów:
-module(all_atoms).
-export([all_atoms/0]).
atom_by_number(N) ->
binary_to_term(<<131,75,N:24>>).
all_atoms() ->
atoms_starting_at(0).
atoms_starting_at(N) ->
try atom_by_number(N) of
Atom ->
[Atom] ++ atoms_starting_at(N + 1)
catch
error:badarg ->
[]
end.
Wyjście wygląda następująco:
> all_atoms:all_atoms().
[false,true,'_',[email protected],'$end_of_table','','fun',
infinity,timeout,normal,call,return,throw,error,exit,
undefined,nocatch,undefined_function,undefined_lambda,
'DOWN','UP','EXIT',aborted,abs_path,absoluteURI,ac,accessor,
active,all|...]
> length(v(-1)).
9821
* W Erlang/OTP 20,0, możesz zadzwonić erlang:system_info(atom_count)
:
> length(all_atoms:all_atoms()) == erlang:system_info(atom_count).
true
No cóż, prawdopodobnie leżę na podłodze, więc nie jest to zła droga. Może zagłębię się w źródło erlang i zobaczę, jak to się dzieje. Przy odrobinie kreatywnego hackery, może uda mi się wejść z konsoli na żywo. – Sniggerfardimungus
Recon https://github.com/ferd/recon ma wsparcie dla parsowania zrzutu awaryjnego. – rvirding