mq_receive выдает ошибку «Сообщение слишком длинное» в NASM - PullRequest
0 голосов
/ 07 апреля 2020

Код NASM, приведенный ниже, является очень упрощенной версией гораздо более крупной программы. Это общий объект, а не .exe; его точка входа - Main_Entry_fn. Он использует очереди сообщений POSIX. Программа работает на двух ядрах. Первое ядро ​​вызывает раздел «Write_Data_To_Memory_fn», где оно получает и обрабатывает сообщения. Второе ядро ​​вызывает раздел «While_Loop_Test_fn», где оно обрабатывает данные и отправляет сообщения.

В этом примере ядро ​​ядра было удалено, так как раздел «While_Loop_Test_fn» (который включает в себя mq_send) был обойден - сначала мне нужно настроить mq_receive для подготовки к приему сообщений.

Очередь сообщений успешно создана и успешно открыта в разделе «Write_Data_To_Memory_fn», но проблема в том, что mq_receive завершается ошибкой с сообщением «Сообщение слишком длинное».

Длина сообщения определяется в узле mq_msgsize структуры атрибутов как 656 байтов. MQ_Receive_Buffer определен как 82 четырехсловных слова для 656 байтов. Третий параметр, передаваемый в mq_receive, также составляет 656 байт.

Страница man Linux в http://man7.org/linux/man-pages/man3/mq_receive.3.html говорит: «Аргумент msg_len указывает размер буфера, на который указывает msg_ptr; он должен быть больше или равен атрибуту mq_msgsize из очереди. " Здесь все ссылки на выходной буфер составляют 656 байтов.

Вот код NASM:

; Header Section
[BITS 64]

[default rel]

global Main_Entry_fn
global While_Loop_Test_fn
global Write_Data_To_Memory_fn
extern mq_open, mq_close, mq_unlink, mq_send, mq_receive,   mq_getattr, perror

%define O_RDONLY     00000000
%define O_WRONLY 00000001
%define O_RDWR 00000002
%define O_CREAT 00000100

section .data align=16
vector_of_8s: times 82 dq 0
MQ_Name: db "/MQ_01",0x00
MQ_FDes: dq 0
MQ_FDes_Core: dq 0
MQ_FDes_Core_02: dq 0
MQ_Receive_Buffer: times 82 dq 0
msg_priority: dq 0
perror_msg: db "Error Number\n"

struc mq_attr
  .mq_flags: resd 1
  .mq_maxmsg: resd 1
  .mq_msgsize: resd 1
  .mq_curmsgs: resd 1
endstruc

mq_attributes:
  istruc mq_attr
    at mq_attr.mq_flags, dd O_RDWR
    at mq_attr.mq_maxmsg, dd 100
    at mq_attr.mq_msgsize, dd 656
    at mq_attr.mq_curmsgs, dd 0
  iend

; __________

section .text

Init_Cores_fn:

; __________
; Set up POSIX message queue

Message_queue:

mov rax,O_RDWR
mov rbx,O_CREAT
or rax,rbx
mov rdi,MQ_Name
mov rsi,rax
mov rdx,777 ; mode
mov rcx,mq_attr
call mq_open wrt ..plt
mov [MQ_FDes],rax

jmp Write_Data_To_Memory_fn

; ______________________________________

While_Loop_Test_fn:

; This section is bypassed for the MCRE example
; It is included here to show how messages are sent with 
mq_send

Open_message_queue:
lea rdi,[MQ_Name]
mov rsi,O_RDWR
call mq_open wrt ..plt
mov [MQ_FDes_Core],rax

; IPC MESSAGE IS SENT HERE
mov rsi,vector_of_8s ; MQ_Message
mov [rsi+80],rbx ;core number

mov rdi,[MQ_FDes_Core]
mov rsi,MQ_Receive_Buffer
mov rax,199
mov [rsi],rax
mov rdx,96
mov rcx,msg_priority

call mq_send wrt ..plt

; __________

label_900:

; Close message queue
mov rdi,[MQ_FDes]
call mq_close wrt ..plt
lea rdi,[MQ_Name]
call mq_unlink wrt ..plt

ret

; __________
; Main Entry

Main_Entry_fn:

push rdi
push rbp
push rbx

call Init_Cores_fn

pop rbx
pop rbp
pop rdi
ret

;__________

Write_Data_To_Memory_fn:

lea rdi,[MQ_Name]
mov rsi,O_RDONLY
mov rdx,777
mov rcx,mq_attr
call mq_open wrt ..plt
mov [MQ_FDes_Core_02],rax

mov rdi,[MQ_FDes_Core_02]
mov rsi,MQ_Receive_Buffer
mov rdx,656
mov rcx,msg_priority
call mq_receive wrt ..plt ; MQ CALL

cmp rax,-1
jne no_error
mov rdi,perror_msg
call perror wrt ..plt
no_error:

jmp label_900

ret

Поскольку все ссылки на размер буфера сообщений одинаковы, почему я получаю сообщение об ошибке «сообщение слишком длинное».

Спасибо за любые идеи.

1 Ответ

0 голосов
/ 07 апреля 2020

Страница man для структуры mq_attr показывает, что все поля в структуре являются длинными, вы определили их как dd, который, если dq равен 8 байтам, будет 4 байтом, поэтому должны ли они быть 8 байтами, а не 4 байтами? Вы не говорите, какую архитектуру вы используете для этого, поэтому 4 байта могут быть правильными.

...