Thread: setlocale(LC_ALL, ""): Erreur de segmentation

  1. #1
    Registered User
    Join Date
    Jan 2017
    Posts
    2

    setlocale(LC_ALL, ""): Erreur de segmentation

    Hello,
    All work fine without non-ascii characters, but I need them.
    Code:
    int main(void)
    {
        wchar_t buffer[10+1];
    
        wprintf(L"Input please: ");
        wscanf(L"%10ls", buffer);
        wprintf(L"--> %zu %ls\n", wcslen(buffer), buffer);
    
        return EXIT_SUCCESS;
    }
    But if I add setlocale(LC_ALL, ""):
    Code:
    int main(void)
    {
        wchar_t buffer[10+1];
        
        setlocale(LC_ALL, "");
    
        wprintf(L"Input please: ");
        wscanf(L"%10ls", buffer);
        wprintf(L"--> %zu %ls\n", wcslen(buffer), buffer); 
    
        return EXIT_SUCCESS;
    }
    All work fine with or without non-ascii characters, but if I input more than 17 characters I have: "Erreur de segmentation (core dumped)"

    gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    38,657
    Your buffer is only 10 characters long, but you input 17.
    What did you expect?

    Allocate a decent buffer size and try again.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Jun 2015
    Posts
    1,643
    Quote Originally Posted by Salem View Post
    Your buffer is only 10 characters long, but you input 17.
    What did you expect?
    The problem is that the wscanf limits the input to 10 characters. If you enter, say, 20 characters, it segfaults with the setlocale call but doesn't segfault without it.
    Code:
    #include <stdlib.h>
    #include <wchar.h>
    #include <locale.h>
    
    int main(void) {
        wchar_t buffer[10+1];
         
    //    setlocale(LC_ALL, "");
     
        wprintf(L"Input please: ");
        wscanf(L"%10ls", buffer);
        wprintf(L"--> %zu %ls\n", wcslen(buffer), buffer); 
     
        return EXIT_SUCCESS;
    }

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    38,657
    Oops - mis-read the input limit, sorry.

    I added some locale debug, and it still crashes.
    But it crashes inside the shutdown code in libc, not the actual program.
    Code:
    $ gcc -g -Wall foo.c
    $ gdb -q ./a.out
    Reading symbols from ./a.out...done.
    (gdb) list
    1	#include <stdlib.h>
    2	#include <wchar.h>
    3	#include <locale.h>
    4	 
    5	int main(void) {
    6	    wchar_t buffer[10+1] = { 0 };
    7	    char *lc;
    8	
    9	    lc = setlocale(LC_ALL,NULL);
    10	    wprintf(L"Old locale=%s\n", lc ? lc : "setlocale failed"); 
    (gdb) 
    11	    lc = setlocale(LC_ALL, "");
    12	    wprintf(L"New locale=%s\n", lc ? lc : "setlocale failed"); 
    13	  
    14	    wprintf(L"Input please: ");
    15	    wscanf(L"%10ls", buffer);
    16	    wprintf(L"--> %zu %ls\n", wcslen(buffer), buffer); 
    17	  
    18	    return EXIT_SUCCESS;
    19	}
    (gdb) b 18
    Breakpoint 1 at 0x400785: file foo.c, line 18.
    (gdb) run
    Starting program: ./a.out 
    Old locale=C
    New locale=en_GB.UTF-8
    Input please: llllllllllllllllll
    --> 10 llllllllll
    
    Breakpoint 1, main () at foo.c:18
    18	    return EXIT_SUCCESS;
    (gdb) p sizeof(buffer)
    $1 = 44
    (gdb) x/44xb buffer
    0x7fffffffddd0:	0x6c	0x00	0x00	0x00	0x6c	0x00	0x00	0x00
    0x7fffffffddd8:	0x6c	0x00	0x00	0x00	0x6c	0x00	0x00	0x00
    0x7fffffffdde0:	0x6c	0x00	0x00	0x00	0x6c	0x00	0x00	0x00
    0x7fffffffdde8:	0x6c	0x00	0x00	0x00	0x6c	0x00	0x00	0x00
    0x7fffffffddf0:	0x6c	0x00	0x00	0x00	0x6c	0x00	0x00	0x00
    0x7fffffffddf8:	0x00	0x00	0x00	0x00
    (gdb) c
    Continuing.
    
    Program received signal SIGSEGV, Segmentation fault.
    __GI__IO_wfile_sync (fp=0x0) at wfileops.c:534
    534	wfileops.c: No such file or directory.
    (gdb) bt
    #0  __GI__IO_wfile_sync (fp=0x0) at wfileops.c:534
    #1  0x00007ffff7a89947 in _IO_default_setbuf (fp=fp@entry=0x7ffff7dd18e0 <_IO_2_1_stdin_>, p=0x0, len=0)
        at genops.c:523
    #2  0x00007ffff7a86439 in _IO_new_file_setbuf (fp=0x7ffff7dd18e0 <_IO_2_1_stdin_>, p=<optimised out>, 
        len=<optimised out>) at fileops.c:451
    #3  0x00007ffff7a8a39f in _IO_unbuffer_all () at genops.c:915
    #4  _IO_cleanup () at genops.c:960
    #5  0x00007ffff7a47f9b in __run_exit_handlers (status=0, listp=<optimised out>, 
        run_list_atexit=run_list_atexit@entry=true) at exit.c:95
    #6  0x00007ffff7a48045 in __GI_exit (status=<optimised out>) at exit.c:104
    #7  0x00007ffff7a2e837 in __libc_start_main (main=0x400696 <main>, argc=1, argv=0x7fffffffdef8, 
        init=<optimised out>, fini=<optimised out>, rtld_fini=<optimised out>, stack_end=0x7fffffffdee8)
        at ../csu/libc-start.c:325
    #8  0x00000000004005c9 in _start ()
    There is no sign of data overrun in buffer, as shown by the x command. Indeed had there been, it would be unlikely that main would have returned successfully.

    This might be a library bug.

    Bugs : glibc package : Ubuntu doesn't show anything relevant for locale, though there are several locale issues.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    Registered User
    Join Date
    Jun 2015
    Posts
    1,643
    Quote Originally Posted by Salem View Post
    I added some locale debug, and it still crashes.
    But it crashes inside the shutdown code in libc, not the actual program.
    Thanks for looking into it. I wonder what's going on? For me, entering 17 or less characaters is okay, but beyond that it segfaults. The cleanup code is choking on those extra characters somehow. Looks very much like a library bug.

    A standard library work-around (and perhaps generally good practice in any case) is to ensure that you read the whole line by using fgetws and checking for the (wide) newline character.
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <wchar.h>
    #include <locale.h>
    
    int main(void) {
        wchar_t buffer[11];
    
        setlocale(LC_ALL, "");
    
        wprintf(L"Input please: ");    
        fgetws(buffer, sizeof buffer / sizeof *buffer, stdin);
        wprintf(L"--> %zu %Ls\n", wcslen(buffer), buffer);
    
        // clear stdin
        while (buffer[wcslen(buffer) - 1] != L'\n')
            fgetws(buffer, sizeof buffer / sizeof *buffer, stdin);
    
        return EXIT_SUCCESS;
    }
    EDIT: Actually, that's some pretty brittle code! Better to make a function. Perhaps:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <wchar.h>
    #include <locale.h>
    
    int get_wide_string(wchar_t *buf, size_t size) {
        wchar_t extra[100];
        if (fgetws(buf, size, stdin) == NULL)
            return -1; // eof or error
        int len = wcslen(buf);
        if (len > 0) {
            if (buf[len - 1] != L'\n')
                do
                    fgetws(extra, sizeof extra / sizeof *extra, stdin);
                while (extra[wcslen(extra) - 1] != L'\n');
            else
                buf[--len] = L'\0';
        }
        return len;
    }
    
    int main(void) {
        wchar_t buffer[11];
    
        setlocale(LC_ALL, "");
    
        wprintf(L"Input: ");
        int len = get_wide_string(buffer, sizeof buffer / sizeof *buffer);
        if (len != -1)
            wprintf(L"--> %d %Ls\n", len, buffer);
    
        return EXIT_SUCCESS;
    }
    This of course assumes that you actually want to throw away any extra characters on the line beyond the given buffer length.
    Last edited by algorism; 01-26-2017 at 03:52 PM.

  6. #6
    Registered User
    Join Date
    Jan 2017
    Posts
    2
    Thank you for your answers.
    Quote Originally Posted by algorism View Post
    This of course assumes that you actually want to throw away any extra characters on the line beyond the given buffer length.
    Yes, this is what I want.
    Quote Originally Posted by Salem View Post
    This might be a library bug.
    Assuming it was a library bug, somebody could report it, my English and my programming skills are too bad for that.
    Last edited by auraes; 01-27-2017 at 12:15 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 2
    Last Post: 12-08-2014, 08:12 PM
  2. Segmentation fault when using fopen("filename","w+")
    By Marslakoo in forum C Programming
    Replies: 6
    Last Post: 11-21-2011, 08:15 AM
  3. [Segmentation Fault] fopen("filename","w")
    By gibbofresco in forum C Programming
    Replies: 7
    Last Post: 07-04-2009, 04:32 AM
  4. "itoa"-"_itoa" , "inp"-"_inp", Why some functions have "
    By L.O.K. in forum Windows Programming
    Replies: 5
    Last Post: 12-08-2002, 08:25 AM
  5. "CWnd"-"HWnd","CBitmap"-"HBitmap"...., What is mean by "
    By L.O.K. in forum Windows Programming
    Replies: 2
    Last Post: 12-04-2002, 07:59 AM

Tags for this Thread