Bug 4646 - Неверное разрешение экрана + падение monitor-get-edid
: Неверное разрешение экрана + падение monitor-get-edid
Status: RESOLVED WONTFIX
Product: Desktop Bugs
Classification: ROSA Desktop
Component: Main Packages
: Fresh
: All Linux
: Normal normal
: ---
Assigned To: ROSA Linux Bugs
: ROSA Linux Bugs
:
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2014-11-11 13:04 MSK by Eugene Shatokhin
Modified: 2015-04-13 17:56 MSD (History)
1 user (show)

See Also:
RPM Package:
ISO-related:
Bad POT generating:
Upstream:


Attachments
Core dumps of monitor-get-edid-using-vbe (104.11 KB, application/octet-stream)
2014-11-11 13:05 MSK, Eugene Shatokhin
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Eugene Shatokhin 2014-11-11 13:04:56 MSK
Железо и логи: http://hw.rosalinux.ru/index.php?probe=48dd18f11c&kind=debug

При выходе из некоторых игр устанавливается неправильное разрешение экрана. 
В системе используется проприетарный драйвер nvidia340.

Возможно, проблема связана с падением monitor-get-edid (они могут быть следствием чего-то общего?). 

Падение это проявляется и при запуске hw-probe.

Обычно monitor-get-edid на системах с пропр. драйверами ничего не выдаёт, но и не падает при этом. На данной системе - не падает, если запустить явно; падает, если hw-probe его запускает.

Вопрос, почему при использовании проприетарного драйвера monitor-get-edid всё-таки запустил monitor-get-edid-using-vbe, хотя и не должен был.

Судя по core dump'ам, вызывались такие команды:
/usr/sbin/monitor-get-edid-using-vbe --port 0
/usr/sbin/monitor-get-edid-using-vbe --port 1 --skip-vbe-check
/usr/sbin/monitor-get-edid-using-vbe --port 2 --skip-vbe-check
---------------------------------------------------------------

Падает во всех случаях с похожими симптомами (см. ниже). Если эти команды запустить явно, они падают именно так.

Core was generated by '/usr/sbin/monitor-get-edid-using-vbe --port 0'.
Program terminated with signal SIGILL, Illegal instruction.
#0  0x00007fa22acc4ecf in LRMI_init () at thunk.c:172
172             *((char *)0) = 0x4f; /* Make sure that we end up jumping back to a
(gdb) bt
#0  0x00007fa22acc4ecf in LRMI_init () at thunk.c:172
#1  0x00000000004017f5 in vbe_check_vbe_info () at vbe.c:128
#2  get_edid (edid=edid@entry=0x7fff9144fb50 "", port=port@entry=0, skip_vbe_check=skip_vbe_check@entry=0) at vbe.c:280
#3  0x0000000000400d77 in main (argc=<optimized out>, argv=<optimized out>) at monitor-get-edid-using-vbe.c:54
(gdb) disas
Dump of assembler code for function LRMI_init:
   0x00007fa22acc4de0 <+0>:     push   %rbx
   0x00007fa22acc4de1 <+1>:     sub    $0x830,%rsp
   0x00007fa22acc4de8 <+8>:     callq  0x7fa22acc4150 <LRMI_common_init@plt>
   0x00007fa22acc4ded <+13>:    test   %eax,%eax
   0x00007fa22acc4def <+15>:    jne    0x7fa22acc4e00 <LRMI_init+32>
   0x00007fa22acc4df1 <+17>:    add    $0x830,%rsp
   0x00007fa22acc4df8 <+24>:    xor    %eax,%eax
   0x00007fa22acc4dfa <+26>:    pop    %rbx
   0x00007fa22acc4dfb <+27>:    retq   
   0x00007fa22acc4dfc <+28>:    nopl   0x0(%rax)
   0x00007fa22acc4e00 <+32>:    mov    0x218139(%rip),%rax        # 0x7fa22aedcf40
   0x00007fa22acc4e07 <+39>:    mov    %rsp,%rdi
   0x00007fa22acc4e0a <+42>:    movq   $0x0,(%rax)
   0x00007fa22acc4e11 <+49>:    mov    0x218148(%rip),%rax        # 0x7fa22aedcf60
   0x00007fa22acc4e18 <+56>:    mov    %rax,(%rsp)
   0x00007fa22acc4e1c <+60>:    mov    0x2181a5(%rip),%rax        # 0x7fa22aedcfc8
   0x00007fa22acc4e23 <+67>:    mov    %rax,0x8(%rsp)
   0x00007fa22acc4e28 <+72>:    mov    0x218121(%rip),%rax        # 0x7fa22aedcf50
   0x00007fa22acc4e2f <+79>:    mov    %rax,0x10(%rsp)
   0x00007fa22acc4e34 <+84>:    mov    0x218175(%rip),%rax        # 0x7fa22aedcfb0
   0x00007fa22acc4e3b <+91>:    mov    %rax,0x18(%rsp)
   0x00007fa22acc4e40 <+96>:    mov    0x2180e9(%rip),%rax        # 0x7fa22aedcf30
   0x00007fa22acc4e47 <+103>:   mov    %rax,0x20(%rsp)
   0x00007fa22acc4e4c <+108>:   mov    0x218125(%rip),%rax        # 0x7fa22aedcf78
   0x00007fa22acc4e53 <+115>:   mov    %rax,0x28(%rsp)
   0x00007fa22acc4e58 <+120>:   callq  0x7fa22acc3f20 <X86EMU_setupPioFuncs@plt>
   0x00007fa22acc4e5d <+125>:   lea    0x30(%rsp),%rdi
   0x00007fa22acc4e62 <+130>:   lea    0x830(%rsp),%rdx
   0x00007fa22acc4e6a <+138>:   mov    %rdi,%rax
   0x00007fa22acc4e6d <+141>:   nopl   (%rax)
   0x00007fa22acc4e70 <+144>:   lea    -0x117(%rip),%rcx        # 0x7fa22acc4d60 <x86emu_do_int>
   0x00007fa22acc4e77 <+151>:   add    $0x8,%rax
   0x00007fa22acc4e7b <+155>:   mov    %rcx,-0x8(%rax)
   0x00007fa22acc4e7f <+159>:   cmp    %rdx,%rax
   0x00007fa22acc4e82 <+162>:   jne    0x7fa22acc4e70 <LRMI_init+144>
   0x00007fa22acc4e84 <+164>:   callq  0x7fa22acc4460 <X86EMU_setupIntrFuncs@plt>
   0x00007fa22acc4e89 <+169>:   mov    0x2180b8(%rip),%rbx        # 0x7fa22aedcf48
   0x00007fa22acc4e90 <+176>:   mov    $0x10000,%edi
   0x00007fa22acc4e95 <+181>:   movl   $0x3200,0x3c(%rbx)
   0x00007fa22acc4e9c <+188>:   callq  0x7fa22acc4090 <LRMI_alloc_real@plt>
   0x00007fa22acc4ea1 <+193>:   mov    %eax,%edx
   0x00007fa22acc4ea3 <+195>:   xor    %esi,%esi
   0x00007fa22acc4ea5 <+197>:   mov    %rax,%rdi
   0x00007fa22acc4ea8 <+200>:   shr    $0x4,%edx
   0x00007fa22acc4eab <+203>:   movl   $0xfff9,0x28(%rbx)
   0x00007fa22acc4eb2 <+210>:   mov    %rax,0x219a4f(%rip)        # 0x7fa22aede908 <stack>
   0x00007fa22acc4eb9 <+217>:   mov    %dx,0x44(%rbx)
   0x00007fa22acc4ebd <+221>:   mov    $0x10000,%edx
   0x00007fa22acc4ec2 <+226>:   callq  0x7fa22acc40d0 <memset@plt>
   0x00007fa22acc4ec7 <+231>:   movb   $0x0,0x0
=> 0x00007fa22acc4ecf <+239>:   ud2 // Crashes here. Indeed, this should have been unreachable.

Код LRMI_init() не совсем обычный:
int LRMI_init() {
        int i;
        X86EMU_intrFuncs intFuncs[256];

        if (!LRMI_common_init())
                return 0;

        mmap_addr = 0;
        
        X86EMU_pioFuncs pioFuncs = {
                (&x_inb),
                (&x_inw),
                (&x_inl),
                (&x_outb),
                (&x_outw),
                (&x_outl)
        };
        
        X86EMU_setupPioFuncs(&pioFuncs);

        for (i=0;i<256;i++)
                intFuncs[i] = x86emu_do_int;
        X86EMU_setupIntrFuncs(intFuncs);
        
        X86_EFLAGS = X86_IF_MASK | X86_IOPL_MASK;

        /*
         * Allocate a 64k stack.
         */
        stack = LRMI_alloc_real(64 * 1024);
        X86_SS = (unsigned int) stack >> 4;
        X86_ESP = 0xFFF9;
        memset (stack, 0, 64*1024);

	// Падает на обработке этого null pointer deref.:
        *((char *)0) = 0x4f; /* Make sure that we end up jumping back to a
                                halt instruction */

        M.mem_base = 0;
        M.mem_size = 1024*1024;

        return 1;
}

Вероятно, libx86 как-то ставит обработчик для null pointer deref. (NPD) либо 
меняет какие-то параметры стандартного обработчика. 
Похоже, что
  *((char *)0) = 0x4f;
в бинарном коде всё-таки соответствует инструкция 
  0x00007fa22acc4ec7 <+231>:   movb   $0x0,0x0

Она должна привести к исключению и передать управление на обработчик NPD. Но почему-то обработчик не вызывается, возможно, это NPD перехватывается кем-то (nvidia340?) раньше, обрабатывается и управление передаётся на инструкцию, следующую за данной. Т.к. та, по изначальной логике, выполняться не должна, компилятор там поставил ud2 (инструкцию, генерирующую исключение "invalid opcode" => SIGILL), вероятно, для защиты от непредвиденных ситуаций.

Эта инструкция и сработала.
Comment 1 Eugene Shatokhin 2014-11-11 13:05:43 MSK
Created attachment 3439 [details]
Core dumps of monitor-get-edid-using-vbe
Comment 2 Eugene Shatokhin 2014-11-11 13:07:06 MSK
О проблеме сообщили на форуме: http://forum.rosalab.ru/viewtopic.php?f=53&t=4661&p=34318
Comment 3 Eugene Shatokhin 2015-04-13 17:56:41 MSD
Тоже может быть полезно:
http://forum.rosalab.ru/viewtopic.php?f=53&t=5437&p=42806#p42799