Bug 47127 - Ошибка сегментирования при использовании ctypes, системных вызовов и inspect
Summary: Ошибка сегментирования при использовании ctypes, системных вызовов и inspect
Status: CLOSED NOTABUG
Alias: None
Product: Sisyphus
Classification: Development
Component: python3 (show other bugs)
Version: unstable
Hardware: x86_64 Linux
: P5 normal
Assignee: Grigory Ustinov
QA Contact: qa-sisyphus
URL: https://www.destroyallsoftware.com/ta...
Keywords:
Depends on:
Blocks:
 
Reported: 2023-08-04 15:41 MSK by Anton Zhukharev
Modified: 2023-08-04 17:43 MSK (History)
6 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Anton Zhukharev 2023-08-04 15:41:19 MSK
Система:
========
ALT Workstation K 10.2 (обновлена 04.08.2023).


Пакеты:
=======

python3-3.9.16-alt1.x86_64


Шаги воспроизведения:
=====================

$ cat << \EOF >> script.py
import ctypes

class utsname(ctypes.Structure):
    _fields = [
        ('sysname', ctypes.ARRAY(ctypes.c_char, 1024)),
        ('nodename', ctypes.ARRAY(ctypes.c_char, 1024)),
        ('release', ctypes.ARRAY(ctypes.c_char, 1024)),
        ('version', ctypes.ARRAY(ctypes.c_char, 1024)),
        ('machine', ctypes.ARRAY(ctypes.c_char, 1024)),
        ('domainname', ctypes.ARRAY(ctypes.c_char, 1024))
    ]

o = utsname()
syscall = ctypes.CDLL(None).syscall
syscall(63, ctypes.byref(o))
import inspect
EOF

$ python3 ./script.py


Фактический результат:
======================

Ошибка сегментирования.


Ожидаемый результат:
====================

Ошибки сегментирования нет.


Частота воспроизведения:
========================

Всегда.
Comment 1 Alexander Makeenkov 2023-08-04 15:53:28 MSK
Воспроизводится в сизифе по шагам из описания.
Comment 2 Gleb F-Malinovskiy 2023-08-04 16:57:04 MSK
Так это и не могло работать.  Во-первых, должно быть _fields_, а не _fields, во вторых:

$ python3 -c 'import ctypes; help(ctypes.ARRAY)' | cat
Help on function ARRAY in module ctypes:

ARRAY(typ, len)
    # XXX Deprecated
$ cat test.py
import ctypes

c_char_array = ctypes.c_char * 65

class utsname(ctypes.Structure):
    _fields_ = [
        ('sysname', c_char_array),
        ('nodename', c_char_array),
        ('release', c_char_array),
        ('version', c_char_array),
        ('machine', c_char_array),
        ('domainname', c_char_array),
    ]

o = utsname()
syscall = ctypes.CDLL(None).syscall
syscall(63, ctypes.byref(o))
print(o.machine)

Вот так даже будет работать, но если вы собираетесь этим на самом деле пользоваться -- WAT! :)
Comment 3 Anton Zhukharev 2023-08-04 17:28:40 MSK
(In reply to Gleb F-Malinovskiy from comment #2)
> Так это и не могло работать.  Во-первых, должно быть _fields_, а не _fields,

Да, уже увидел, спасибо :)


> во вторых:
> 
> $ python3 -c 'import ctypes; help(ctypes.ARRAY)' | cat
> Help on function ARRAY in module ctypes:
> 
> ARRAY(typ, len)
>     # XXX Deprecated
> $ cat test.py
> import ctypes
> 
> c_char_array = ctypes.c_char * 65
> 
> class utsname(ctypes.Structure):
>     _fields_ = [
>         ('sysname', c_char_array),
>         ('nodename', c_char_array),
>         ('release', c_char_array),
>         ('version', c_char_array),
>         ('machine', c_char_array),
>         ('domainname', c_char_array),
>     ]
> 
> o = utsname()
> syscall = ctypes.CDLL(None).syscall
> syscall(63, ctypes.byref(o))
> print(o.machine)
> 
> Вот так даже будет работать, но если вы собираетесь этим на самом деле
> пользоваться -- WAT! :)

На самом деле я просто пытался разобраться с использованием ctypes в Python (честно говоря, мне не понравилось - проще уж на Си писать).
И мне другой системный вызов нужен был :)

Крест на конкретно этой затее поставила константа 65 (длина полей в utsname), которую в Python в общем случае в рантайме не определить (судя по исходникам, значения размеров тех или иных полей могут быть разными). :(
Comment 4 Gleb F-Malinovskiy 2023-08-04 17:43:58 MSK
(In reply to Anton Zhukharev from comment #3)
> проще уж на Си писать).
+1

> Крест на конкретно этой затее поставила константа 65 (длина полей в
> utsname), которую в Python в общем случае в рантайме не определить
Да ведь константа 63 тоже ничем не лучше.