Here is small test C program which just intentionally crashes:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
char *l = getenv("LANG");
printf("LANG = %s\n", l);
int *ptr = (int*)0x12345;
*ptr = 12345;
return 0;
}
"Output":
$ ./a.out
LANG = ru_RU.UTF-8
Ошибка сегментирования
The message about crash is in Russian, in accordance with the LANG environment variable value, ok. Now, I want to see the message about crash in English ("Segmentation fault"), but running the program with explicit "LANG=C" does not work:
$ LANG=C ./a.out
LANG = C
Ошибка сегментирования
Why is the message still translated?
My system: Linux Mint 21.3 (Virginia), gcc 11.4.0.
$ locale -a
C
C.utf8
...
An addition, another similar example (double free):
#include <stdio.h>
#include <stdlib.h>
int main(void) {
char *l = getenv("LANG");
printf("LANG = %s\n", l);
int *ptr = malloc(128 * sizeof(int));
free(ptr);
free(ptr);
return 0;
}
- Output when
LANG=ru_RU.UTF-8
$ ./a.out
LANG = ru_RU.UTF-8
free(): double free detected in tcache 2
Аварийный останов
- Output when
LANG=C
$ LANG=C ./a.out
LANG = C
free(): double free detected in tcache 2
Аварийный останов
From /usr/share/locale-langpack/ru/LC_MESSAGES/libc.mo:
msgid "Aborted"
msgstr "Аварийный останов"
When you put a variable assignment at the beginning of the command, the environment variable is only exported to the child process that executes the command, it's not in the environment of the current shell process.
When a process crashes due to a signal, the description of the signal is written by the shell process. So it's using your original
LANGenvironment, not the environment of the subprocess.To get the error message in
LANG=Cyou need to run the program from a child shell: