2Sjch8AT
Finding the cause of stucked beam
I have a program that creates multiple connections to MQTT servers. After a certain numbers of connections are created (>300), the Beam VM becomes frozen. When starting the observer before starting the connection, we can see the schedulers jump from ~30% utilisation to ~100% and the Beam VM is stuck enough that switching tabs on the observer or entering commands in iex is almost impossible.
I was able to generate an Erlang crash and read the states of the processes:
Process States when crashing (sum):
===
1 CONNECTED
1 CONNECTED|BINARY_IO
351 CONNECTED|BINARY_IO|PORT_LOCK
1 CONNECTED|BINARY_IO|SOFT_EOF|PORT_LOCK
1 CONNECTED|DISTR|PORT_LOCK
1 CONNECTED|SOFT_EOF
8 Current Process Internal ACT_PRIO_NORMAL | USR_PRIO_NORMAL | PRQ_PRIO_NORMAL | ACTIVE | RUNNING
8 Current Process Running
1 Internal ACT_PRIO_HIGH | USR_PRIO_HIGH | PRQ_PRIO_HIGH | OFF_HEAP_MSGQ
5 Internal ACT_PRIO_MAX | USR_PRIO_MAX | PRQ_PRIO_MAX
1 Internal ACT_PRIO_MAX | USR_PRIO_MAX | PRQ_PRIO_MAX | OFF_HEAP_MSGQ
2603 Internal ACT_PRIO_NORMAL | USR_PRIO_NORMAL | PRQ_PRIO_NORMAL
1 Internal ACT_PRIO_NORMAL | USR_PRIO_NORMAL | PRQ_PRIO_NORMAL | ACTIVE | RUNNING
332 Internal ACT_PRIO_NORMAL | USR_PRIO_NORMAL | PRQ_PRIO_NORMAL | IN_PRQ_NORMAL | ACTIVE | IN_RUNQ
3 Internal ACT_PRIO_NORMAL | USR_PRIO_NORMAL | PRQ_PRIO_NORMAL | IN_PRQ_NORMAL | ACTIVE | IN_RUNQ | SIG_IN_Q | ACTIVE_SYS
1 Internal ACT_PRIO_NORMAL | USR_PRIO_NORMAL | PRQ_PRIO_NORMAL | IN_PRQ_NORMAL | ACTIVE | IN_RUNQ | SIG_IN_Q | ACTIVE_SYS | SIG_Q
1 Internal ACT_PRIO_NORMAL | USR_PRIO_NORMAL | PRQ_PRIO_NORMAL | IN_PRQ_NORMAL | IN_RUNQ | SIG_IN_Q | ACTIVE_SYS
1 Internal ACT_PRIO_NORMAL | USR_PRIO_NORMAL | PRQ_PRIO_NORMAL | IN_PRQ_NORMAL | IN_RUNQ | SIG_IN_Q | ACTIVE_SYS | SIG_Q
5 Internal ACT_PRIO_NORMAL | USR_PRIO_NORMAL | PRQ_PRIO_NORMAL | OFF_HEAP_MSGQ
1 Running
338 Scheduled
2615 Waiting
-
What is
PORT_LOCK? Is it bad? -
I have access to the source of the application and its libraries sources, how can I track down the problem?
Marked As Solved
2Sjch8AT
Thanks everybody for the help. I have open an issue in the Tortoise repository.
Also Liked
NobbZ
Wait? You are creating and destroying network namespaces dynamically in a large scale?
We had some similar setup up for some simulated network testing a few years ago.
We created and destroyed many hundred namespaces per hour, and the system call that should create the next one simply just stalled when it should create the nth namespace.
The OS thread responsible for this call just wouldn’t be scheduled by the OS anymore and wasn’t even kill -9able. Even worse, when the parent was killed, the stale child “survived”.
It was not possible to create any further namespaces when this occured. n was constant per machine across reboots, but different on a couple of hosts we tested.
Back then my personal funtoo machine survived the most namespaces, somewhere in the 10s of millions, where most other systems staled already in single digit millions.
We were not able to hunt down the root cause, as the affected client decided to just use a VM which gets thrown away after a couple of those iterations when we are still in a safe area of already created namespaces.
So if you really do work with a huge number of dynamically created and deleted namespaces, check if any of the described symptoms happen to you as well.
PS: We did not use erlang for that project, though it seemed to be a limitation of the OS, not of erlang.
OvermindDL1
Zombie process!
It happens because programs have a few states they can be in:
- Active_Scheduleable
- Sleep_Scheduleable
- Wait_Scheduleable
- Wait
Scheduleable means the process is in a coherent enough state so it can receive signals. If it’s not scheduleable then the process is waiting on something deep in the kernel.
The ‘Wait’ one generally only happen on very few specific kernel primitives, accessing low level resources like allocating new network data (not accessing it) is one. If the kernel can’t create it because it’s out of space for it then the program will wait until there are available resources. If the program is the one that caused the kernel to run out of the resources then it is a Zombie, forever dead and inaccessible as there isn’t a single signal in the entire system that can access it, not even kill -9.
garazdawi
These lines are actually Port states, not Process states.
The PORT_LOCK refers to the fact that the Port is locked using a port specific lock instead of a driver lock. This is normal and nothing to worry about.
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance










