Why does not 'LANG=C' affect "Segmentation fault" message?

61 Views Asked by At

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;
}
  1. Output when LANG=ru_RU.UTF-8
    $ ./a.out 
    LANG = ru_RU.UTF-8
    free(): double free detected in tcache 2
    Аварийный останов
  1. 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 "Аварийный останов"
1

There are 1 best solutions below

2
Barmar On

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 LANG environment, not the environment of the subprocess.

To get the error message in LANG=C you need to run the program from a child shell:

LANG=C bash -c './a.out'