Is there any method to specify the size of message?. For example if i want to send message data through channel AB then how can I specify the size of data in PROMELA language?
The syntax for declaring a channel is, for example:
chan ab = [16] of { short }
ab is the identifier bound to the channel. 16 is the number of messages in the channel. short is the data type of each message.
When you specify the message type you have a number of additional options:
char ab = [16] of { byte, short, bit }
which creates a channel with each message being: byte, short, and bit. In such a case it is often better to create a new type with:
typedef message {
byte operator;
short data;
bit what;
};
and then
chan ab = [16] of { message }
Related
I got the string \x01\x01 from a tcp/ip socket, when I try to print it to console, no output is coming
void main() {
var out = "\x01\x01";
print("printing out as --> $out <--");
final runes = out.runes.toList();
print(runes);
}
It gives the output as
printing out as --> <--
[1, 1]
dart pad link: https://dartpad.dev/?id=854e4479bfec03d7e8fd40621c845567
I tried to use hex package and it gives Non-hex character detected error.
Questions.
How do I print these types of strings to the console?
If some conversion is needed, how do I know data belongs to these type ?
my socket client is like the following
socket.listen(
// handle data from the server
(Uint8List data) async {
var serverResponse = String.fromCharCodes(data);
print('Server: $serverResponse');
final runes = serverResponse.runes.toList();
print(runes);
},
EDIT
The socket server is the x0vnc server, on reading the input with wire shark I can see the server sent 01 01
To display a hexa, you have to escape the characters like this:
var out = '\\x01\\x01';
this will work.
I suspect you have misunderstood what the server is sending.
Given you've not stated the server language I'm going to guess that ` ab = b'\x01\x01' generates a array with two bytes both with the value 1.
If you treat this as an ASCII value then 1 is a non printable character.
As such you need to iterate over the array and convert each byte into a suitable visual format.
This might mean that when you see a 1 you print x01.
Edit:
actually dart will convert an int to a string for you:
void main() {
final bytes = <int>[1, 2, 3];
for (final byte in bytes) {
print(byte.toString());
}
}
When I try to match a message in a receive statement I get a "bad node type 44" error message. This happens when the message's type is a typedef. The error message is rather cryptic and doesn't give much insight.
typedef t {
int i
}
init {
chan c = [1] of {t}
t x;
!(c ?? [eval(x)]) // <--- ERROR
}
Note: This may, or may not, be a bug in Spin: apparently, the grammar allows using a structure variable as an argument for eval(), but it does not look like this situation is handled correctly (within the extent of my limited understanding). I would encourage you to contact the maintainers of Promela/Spin and submit your model.
Nevertheless, there is a work-around for the issue you reported (see below).
Contrary to what is reported here:
NAME
eval - predefined unary function to turn an expression into a constant.
SYNTAX
eval( any_expr )
The actual promela grammar for EVAL looks a bit different:
receive : varref '?' recv_args /* normal receive */
| varref '?' '?' recv_args /* random receive */
| varref '?' '<' recv_args '>' /* poll with side-effect */
| varref '?' '?' '<' recv_args '>' /* ditto */
recv_args: recv_arg [ ',' recv_arg ] * | recv_arg '(' recv_args ')'
recv_arg : varref | EVAL '(' varref ')' | [ '-' ] const
varref : name [ '[' any_expr ']' ] [ '.' varref ]
Take-aways:
apparently, eval is allowed to take as argument a structure (because name may be the identifier of a typedef structure [?])
eval can also take as argument a structure field
when one aims to apply message filtering to an entire structure, it can expand the relevant fields of the structure itself
Example:
typedef Message {
int _filter;
int _value;
}
chan inout = [10] of { Message }
active proctype Producer()
{
Message msg;
byte cc = 0;
for (cc: 1 .. 10) {
int id;
select(id: 0..1);
msg._filter = id;
msg._value = cc;
atomic {
printf("Sending: [%d|%d]\n", msg._filter, msg._value);
inout!msg;
}
}
printf("Sender Stops.\n");
}
active proctype Consumer()
{
Message msg;
msg._filter = 0;
bool ignored;
do
:: atomic {
inout??[eval(msg._filter)] ->
inout??eval(msg._filter), msg._value;
printf("Received: [%d|%d]\n", msg._filter, msg._value);
}
:: timeout -> break;
od;
printf("Consumer Stops.\n");
}
simulation output:
~$ spin test.pml
Sending: [1|1]
Sending: [0|2]
Received: [0|2]
Sending: [0|3]
Received: [0|3]
Sending: [0|4]
Received: [0|4]
Sending: [0|5]
Received: [0|5]
Sending: [1|6]
Sending: [0|7]
Received: [0|7]
Sending: [0|8]
Received: [0|8]
Sending: [1|9]
Sending: [1|10]
Sender Stops.
timeout
Consumer Stops.
2 processes created
Generating a verifier does not result in a compilation error:
~$ spin -a test.pml
~$ gcc -o run pan.c
Note: when using both message filtering and message polling (like in your model sample), the fields of the structure that are subject to message filtering should be placed at the beginning of it.
Apparently it's a bug, link to github issue: https://github.com/nimble-code/Spin/issues/17
Update: Bug is now fixed.
Update 2: Bug was actually partially fixed, there are still some edge cases where it's behaving weirdly.
Update 3: As far as I can tell bug looks fixed now. The only downside is that it seems that now there is a strict restriction on what you put in the receive args. They have to match exactly the types declared in the channel. No more partial matches or unrolling struct fields.
My guess is that this error is related to the restrictions that structured types have. One restriction is that they can't be handled as a unit, to assign or compare them one must do it one field at a time.
For example, if one writes: x == y, where x and y are variables of a typedef type, the following error is shown: Error: incomplete structure ref 'x' saw 'operator: =='
Under the hood, when trying to compare the channel's queue to match the eval something is triggered that indicates that the comparison can't be done and then raises the "bad node type" message.
When designing models in Promela, what are the design trade-offs for channels when there are a many different types of messages being sent?
Many examples in documentation use a simple case with something like this
mtype { M1, M2, M3 }
chan req = [0] of { mtype, chan, byte};
However in practice some models may have processes that handle a wide variety of different message types, each of which have a unique set of parameters.
So there seems to be a design decision between channels that can represent the parameters of a variety of message types:
mtype { M1, M2, M3 }
chan req = [0] of { mtype, chan, byte, int, byte, etc...};
and channels specific to each message type
chan req1 = [0] of { chan, byte };
chan req2 = [0] of { chan, int };
chan req3 = [0] of { chan, byte, int};
I'm interested in understand any performance benefits to one design over the other, and what is considered best practices.
this is the code to remove the characters from one string, say p, which are there in the other string, say s, and finally concatenate the two strings and print the final string.
for ex: if inputs are
stringP= "Hello"
StringS= "fellow"
output: Hfellow
another EX
input
stringP= "Android"
StringS= "Google"
output
AndridGoogle
the comparison of the characters is case sensitive.
Currently i am getting segmentation fault after entering the first string. Can anyone please help me in correcting this code? and also why segmentation fault occurs, in which scenarios it occurs?
Thanks in advance.
#include <stdio.h>
#include<string.h>
void remove_char(int *len, char *string1);
int main()
{
char *p,*s,*t;
int len1,len2,i,j;
printf("enter the two strings\n");
scanf("%s",p);
scanf("%s",s);
len1=strlen(p);
len2=strlen(s);
for(i=0;i<len1;i++)
{
for(j=0;j<len2;j++)
{
if(*p==*(s+j))
{
remove_char(&len1,p);
}
if(*p=='\0'||*(s+j)=='\0')
{
break;
}
}
p++;
}
strcat(p,s);
strcat(t,p);
printf("%s",t);
return 0;
}
void remove_char(int *len, char* string1)
{
int a;
for(a=0;a<*len;a++)
{
*string1=*(string1+1);
string1++;
}
len--;
}
The declaration char* p says that p is a variable that contains the address of a character (or potentially the address of a character array).
In your code, you do create storage space for the character (or the array). Think of it this was, p is an alias for a location in the local stack frame (say a four-byte area), and it's contents are interpreted as an address in the heap.
Now, no where in your code to you actually allocate memory, to do this you would need to do something like this:
p = malloc(15*sizeof(char));
This is assuming that you want the user to enter a string of no more than 14 characters (don't forget the null-terminator). Now p contains the address of an area on the heap that can be used to store characters.
So, to answer your question, you are getting a segmentation fault after entering the first string because you failed to allocate memory to store the string in.
Also, note that scanf is insecure in that it will take a string as long as the user feels like typing in and this could result in heap-based buffer overflow. If you want to read in a string of at most 14 character, try this;
#define STR_LEN 14
char* p = malloc(STR_LEN*sizeof(char));
scanf("%STR_LENs", p);
Notice that I have put a length in the specifier so that scanf will limit itself to reading in at most STR_LEN characters. This will help prevent over-flows, not entirely prevent it.
The solution in the post below doesn't work for me. I get error message "Message too long". What can be the problem?
How to send integer with message queue with POSIX API in linux?
If I am correct a pid_t is defined as an int. I have done the following:
struct mq_attr attr;
attr.mq_flags = 0;
attr.mq_maxmsg = 1000;
attr.mq_msgsize = sizeof(pid_t);
mqd_t queue = mq_open(unique_name, O_RDWR|O_CREAT, 0600, &attr);
mqd_t result = mq_send(queue, &pid, sizeof(pid), 0);
I get the following error at compilation at the line of mq_send:
"passing argument 2 of 'mq_send' from incompatible pointer type"
"initialization makes pointer from integer without a cast"
The problem was that I never did mq_unlink.
You probably want to set the maximum message size and queue size with an mq_attr first. See this post for more detail on POSIX queues.