I ran into a problem a while ago, the program somehow crashed and the stack didn’t show anything. Today, I changed a parameter to make the golang program core dump when it crashes.
In fact, the core is to add an environment variable, GOTRACEBACK=1
. But there are some other system-related issues, which I will briefly document in this article.
After Golang 1.6, there have been some changes to the optional values of this environment variable, the new values are as follows:
GOTRACEBACK=none
will suppress all tracebacks, you only get the panic message.GOTRACEBACK=single
is the new default behaviour that prints only the goroutine believed to have caused the panic.GOTRACEBACK=all
causes stack traces for all goroutines to be shown, but stack frames related to the runtime are suppressed.GOTRACEBACK=system
is the same as the previous value, but frames related to the runtime are also shown, this will reveal goroutines started by the runtime itself.GOTRACEBACK=crash
is unchanged from Go 1.5.
Some points to note:
First, an introduction to some other very useful environment variables that can control the golang runtime in addition to this GOTRACEBACK
parameter, as summarized nicely in this article.
Then this parameter is not valid on macOS, so don’t waste your time on MAC.
Linux is also limited by ulimit. You can check the size limit on Core dumps with ulimit -c
. If it’s 0
it won’t dump, and it’s not recommended to set it to ulimited
. If the application is started with systemd, you can set the LimitCORE=
parameter in the service unit file to have the same effect.
Where is the generated core dump stored?
You can check this with the following command.
|
|
This defines how the core dump file is named.
However, in ubuntu, you will see the following output.
|
|
This means that it is directed to apport via pipe. apport is the core dump management service that the ubuntu distribution has chosen to use.
By default, user programs do not have core dumps. We then have two solutions:
- disable apport and use the system’s core dump to write directly to disk
- configure apport to also write the user’s core dump file
The first method is relatively simple. Just modify the /proc/sys/kernel/core_pattern
file in the above section.
Note that there is a small issue to be aware of here: this configuration is global and can only be edited by the root account. This will not work under a normal user, because in this line echo is executed with sudo, but the redirection is actually done by the shell (bash), and the redirection, i.e. the actual writing, is not actually done under root, so you will get the error: Permission denied, or Destination /proc /sys/kernel not writable.
|
|
The solution is to use the following command.
|
|
Then you can disable apport.
For the second method, first make sure that apport is running. You can check this with systemctl status apport
. You can also look at the apport logs.
|
|
Trigger a core dump and you will see:
|
|
This means that the core dump is not from an ubuntu package and is ignored.
To configure this, modify the ~/.config/apport/settings
(if you don’t have it, create it manually) file and write the following.
Trigger another core dump, and this time the log will have the information written to it.
|
|
Note also that this file is not a core dump file, but a debug file packed by apport and can be unpacked using apport-unpack
.
|
|
The unpacked CoreDump can then be analysed with gdb. The other files record some system-related information. (It feels like Ubuntu uses it to allow users to report bugs)
Finally, if the core dump is not generated under the workdir of the process, see if it is in /var/lib/systemd/coredump/
. The internet says that systems using systemd store it there, but I haven’t come across it.