 Думается мы оценили. Как вообще это? Да, это за район. Я в новом капоте режу. Вы с видом сделали. Я не знаю. Как? Нет, это для себя сложно придумать. О, спасибо. А это для следующего очень не прощает. А то просто вот, конец. Перезыхай всем. А, начну так. Просто включай вместе. Вверх и вверх. Не будет у тебя ноут? Не будет у тебя ноут? Нет. Ну, ноут. А это для тебя? Нет. Нет. Это для вас. Нет. Нет. Нет. Нет. Нет. Нет. Нет. Нет. Нет. Нет. Так что я буду говорить о том, что еще новое фич на стрессе, не только в мертвых, но и очень скоро, в структуре output на стрессе. Стресса, Дмитрия уже сказал про стресса и как это работает, и это типичное output на стрессе. Как вы видите, это довольно си-лайк с 1991 года, но, в принципе, не си-лайк, это более нередко. Это перси-лайк. Это как сис-кл, декоза, декоза, вставляет. Это прозатор, сис-кл, си-лайк. Это в данном случае си-лайк, в данном моменте. Это декоза. Как вы already know, стресс interrupts the tracer twice. First on entering the sys-call, and then on exiting the sys-call. So this is what happens on entering, this is what happens on exiting. These two functions print xval and print itimerval. First fetch and then immediately print the values. The second value, car value pointer is a so-called out value. This is where the kernel returns the value. This is why we have to sprint the decoder in two parts. On entering we print what we can print, the first half, and on anything we print the second part. As you can imagine, if there are in-out arguments or multiple out arguments, it gets pretty messy, we have to stash very somewhere, if it's not properly split in half, etc. Also you can see here that every sys-call parser has to print various commas. We can accidentally forget to print commas, and all this code looks pretty bad. This is another sys-call parser. Here we print a complex struct. Everything is printed by hand. This is bad. This is very bad and redundant. So what I told you about not actually being see-like. This is except for. And the third argument is an in-out argument from the main page. The adder-line argument is a value result argument. The caller must initialize it to contain the size of the structure. On return it will contain the actual size of the pure address. This is the send-to sys-call. The first value is a socket. And this arrow is not an in-out value. This is the listener and receiver, IP and port. And this is the listeners sys-call. And this is not an IP or a port. This is an inode of the socket. This is set-eye-timer nested structs. The outer struct doesn't have a name, but the inner structs do have names. And the fields of the structs don't have names. The third argument is not actually an array. It's a bitmask, which has... To feel it, we have... The kernel has special functions, but it's printed like an array without commas. This is exactly... It's not even printed properly. So what's the problem? People try to parse this. This is a tool to convert an output to an easy-to-parse CSV. An ending struggle. To properly parse everything, these parsers have to re-implement strays almost. This is strays to CSV. Regexps again. Eternal suffering. This is something in Perl for change. This is an AVK. This is actually used in Build Rec, a program from Alt-Linux used to fetch built requires. The entire build of a package is stressed, and then the stress output is parsed. Like this. Strays doesn't only print CSV. It can dump data. Minus E write equals 1. It can print CSV statistics. Note the errors column. No zeros, but the microseconds don't have zeros. What if people try to parse this? So we have to separate parsing and printing. We need a whole new approach. Eugene, come here. Tell us the boring part. Well, for the boring part. As you've already seen, the strays output is human-oriented. It is human-oriented on purpose. It originally meant to be read by humans, and is not intended to be read by machine. As a result, it has a lot of peculiarities. And all the strays decoders have been written with this idea in mind. The lot of decoders, as a result, which just print the output in human-readable form. Read it and print it. So in order to get ability to have printed in some other form, we should split fetching of argument data into some internal form, and printing it in some form, which could be human-readable, or machine-readable, or whatever. So, as I already said, decoders try to do everything. And inherently, it is bad, because they print commas and stuff. And it would be much better if we free them from this burden and make all these decoders just do decoding, actually. And add some printers, which would do printing from some internal representation. So, as such, do only one job. And printers themselves should be as local as possible, because now the stress itself — the stress core code — — prints something regarding, well, when it handles ptrace error codes, when it handles exits, when it handles everything, it prints something. And decoders themselves print something, and it should be done, it is done currently in some synchronous way. Таким образом, we are taking account that the brackets already printed, the line return is printed or not, or have we printed that something since we do the line return or not, all this stuff. And in order to do this, we have to introduce some middle layer, which, well, decoders, and on the other side, which allows the writing code format, as well, quite trivial. So, currently, all the Cisco-related information is stored in Tracy control block. It already contains data, which is retrieved by strace, such as Cisco name, which could be different from actual name now, since actual Cisco ID now, since here is fault injection, took place, here is retrieved argument, well, arguments themselves, but not the data, to which argument points to it. It is the job of decoders to retrieve and so on. So, it is augmented with some storage for internal representation of this argument. And in addition, some state is added, which allows decoders to... well, which frees decoders from tracking current printing states themselves. For example, whether we are in structure, whether we are printing one argument or another. For example, some system calls have arguments of type long-long. On 32-bit architectures, these arguments occupy two registers, or double the stack space. On 64-bit architectures, this argument occupies a single register. So, when you're trying to print this argument, you should handle somehow this fact and calculate the number of the next argument, depending on the architecture, at least in code. Yeah. So, what this internal representation does is it basically enables storing each entity, which has its own peculiarities in printing as a separate type, as entity of separate type. So, in order to enable formatter to handle variations in size, in sign-adness, in formatting itself, for example, shouldn't print it in hex, or octal, or anything else. Or, more interesting, for example, if you're trying to print user IDs, then usually you have one special value, minus one, which is invalid value for one CIS-course and the special value for other CIS-course. But, nevertheless, in both cases, it's a special value and it's better when it is printed as minus one and S-trace already does this. And we should account it, because, well, otherwise, for minus two, it should print as for billions and something. And so on. So, in order to allow to use these types appropriate API-course are added and not only for some basic types, which allows parts, well, arguments as entities with some semantics, but also for typical types, which already has implementations-trace, like time wall, like some structures, most of the structures, socket other starter files, well, there are plenty of them. And for some miscellaneous API-course for handling calls and stuff. Well, and formators themselves implement rather trivially as a set of functions and in order to select one formator or another, just pointer to structure containing pointers to this formator should be set and then stress just causes this pointer. So, well, how it looks like. So, there is something called decoder similar to one you have seen already, which of printing some values directly now pushes this data into some internal representation, which is some linked list, which can point to different internal structures, for example swap flux is a value, which has two parts, this flag and another is swap file priority and it should be decoded accordingly as a set of flux and some value. So, and then this internal representation can be parsed by various decoders in order to print actual output. There is legacy decoder, which prints totally this representation in some JSON schema. So, well, as I said there are well, most of the IP calls is just insertion and pushing. Well, insert something is, well, insert something at current insertion point inside structures on arrays or something and push is a shortcut, and also push yet another argument and move pointer to current argument to the next argument, depending on the argument size. For example, I described the issue with long long. So, there is additional handling of arrays and in out arguments they because of on exiting we would like to also have some easy way to say that, well, this argument is well, I like to push next out argument and then next out argument and something. And, well, something Mr. Venous, like pushing empty arguments because, well, for some structures or some cases there is arguments which are not actually used or ellipses it's just well, artifact of current implementation of legacy decoded because arrays should be terminated in accordance with max Australian value and it's currently a way to implement this. So, the formation upon decoder is, well, originally is was like this. You can see that there is the issue with flag parsing. So, if there are flags that we parse them in priority or so, you see, it's well, as you have already seen it was very peculiar code and now it can be more straightforward and there are many other examples where decoders became easier, much more easier and straightforward due to this conversion. And this is example of some JSON which is actually readable it's an example of get random output so what can be seen there well, basically, I don't know because it doesn't matter because the JSON schema itself is just dump of current internal representation For example, it has some non-stabilized features and so on so, well, it is not even documented so it doesn't matter how it looks like well, yeah. Back a slide. When traces the program these blocks of JSON are printed live this is the first thing I want to note and second, JSON and traditional output are not the only options if we see an example of some other printer driver we will implement an option to load the printer as a library so, c3, whatever so, well what now enables the output enables less redundancy it enables well since all decoders are touched in any way it also allows do some code polishing and finally write some argument names for example, for some CTL or key CTL EO CTL well, PR CTL and other decoder syscalls which are have which are just dispatcher syscalls and nobody remembers what arguments actually mean without without looking at the main page for example, for key CTL syscalls so, it enables implementation of some new features and struggle finally ends, hopefully so, well it's not finished yet and it the current effort is software shifted so, when it started it became it's realized that well in order to bring this to the master all syscalls decoder should be covered in tests and it is not the case currently so on and basically that's all so, thank you this is address of repository the work is done which could be third so, you are welcome so, any questions? question, one well, yeah so, how multi-process is handled in s-trace s-trace itself handles multi-processing in the way it sequences them so, it already handles all the issues with which multiple processes like well, one system call is started by and process has gone to sleep, but there is another one s-trace already handles it s-trace already can print output for various processes to various files to different files well so, the question is whether there is one internal representation or multiple so, each tracy, each process has its own tracy control block so, when there are multiple processes, there are multiple tracy control blocks and well each process has its own internal representation or the currency is called shiny stuff is going to be available for median user the question is where this would be available well, it's a tough question because as I said the work on this branch is well it's hard to work inspired some changes in the master and while when you change the master it means that you should re-base the development branch you have to constantly run after you merging new features in master you have to re-base and re-base well, so, my expectation it's like something around 4.17 4.18 not earlier 1 2 3 4 5 6 7 8 9 9 10 11 12 13 14 15 16 17 18 19 20 20 21 22 23 24 25 26 27 28 29 30 30 40 50 50 50 50 50 50 50 50 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 20 21 22 23 24 25 26 27 28 29 30 30 21 22 23 24 25 26 27 27 27 27 27 27 27 27