 Hello, this is talk about GDB tools and GDB tools is so because I see many have opened the laptop I start from the what usually should be at the last slide so GDB tools is a Python package it's on Pi PI so you can install it and you can actually install it right now if you have a laptop open then you can try some simple things during the talk but first I'll be talking about pretty printer and GDB tools contains it's a Python package contains of two modules and pretty bit into the first one dual of the second one that's actually pretty printer and first let me ask who knows the GDB has a Python API yeah obviously and who tried to do something with Python in GDB and who knows what pretty printers are okay and who wrote a pretty printer jake equation yeah okay so so then at least some of you will recognize the pain and some others will see an interaction so that's how most of examples I'm so I'm my DDB developer before that I was my school developer so I spent many hours per week inside GDB inside my school D and most of the examples in this talk are taken straight from my GDB history so they'll practical they'll real nothing hypothetical so that's basically how usually my debugging session goes when I need to print some of the say so say easy structures this one is a bit mapping I want to print it so I print it and then I get to print the structure and then I need to print the array of integers and only 52 bits of it are valid so this is valid and this end of it is valid and this is some garbage so but I shouldn't don't want to care about garbage I just want to see those bits and there's a string object inside my cell may be it's a string as a pointer and this is in the interesting part because this is the length and the rest again is garbage and I don't really want to see the rest of it I just want to see the string and that's why GDB introduced pretty printers yeah and there are also complex structures and that's my my probably most hated example so a skill mode it's a 64-bit integer where every bit means something and when I want to print it so I print it I get some number then I pretend binary and then I try to figure out what combination of bits creates exactly the same number and then I eventually arrive at the same number then I got it that actually takes to mean is just to print a variable and this is not my adb related this from gdpc it's in your system includes it's a color storage when you print it you get a first number which tells you what those bytes mean then you need to interpret them according to this number and I happen to know this one means IPv4 so I can print this when these numbers and I get IPv4 it's not the easiest to print easiest to debug structure so this why GDB into GDB has considered pretty printers and when I finally got pissed off all what I've just have shown I created I finally decided to write a pretty printer and this is how the DB has a pretty good documentation so this is how it usually goes so you need to create a class that gets GDB value is an argument so you need to save it because later you need to use it and then you need to write the actual code that you care about how to convert the value to the string that you want to see when you debugging then it then I do it for the second class because I wanted to start from two pretty printers then I need to create some something which called collection pretty printer then I need to add those printers repeating the class name three more times so it's the class name is repeated four times just on one slide and the second format for more time for the second class then I need to register it and then I'm done and by that time I already annoyed because this is because this is what I want to write this what I want to write and not the rest and that's my problem with this API something laptop is slow what so and I need to write a lot of code that I don't really care about and actually I just started because I wanted to have five or six pretty printers and I also want to recognize pointers so it will be like 12 12 different pretty printers already tied of copy pasting so this why I mean that you have created this pretty printer decorator where this is pretty much self-documenting because this is the class name and this is the code that I care about and again this is the class name this is called the care about nothing else is hidden beside the pretty printer decorator and then it's much easier to write much easier to write and much less code and no copy pasting anymore and after that my debugging sessions they go something like this so bitmap printed at bitmap strings are pretty strings when I print this set of bits I get immediately to be it's deciphered in a way so and this is how I can store just interesting so this was very quick and this was pretty printer now the more a lot more complex model and more interesting for me this is the language dual with a strange acronym debugging you might even like so let me first talk about the history of dual so my personal and first encounter was dual was like 15 years ago when I was debugging some my school bug on some old RX and I cessation to into it and I was doing something in JDB and I did JDB help and I saw a strange command called dual which I haven't seen in JDB before so I did help and it was something cool for printing linked list and arrays and I loved it and I wish links had it and it didn't so I forgot about it then five years later for some reason I remember it and I googled I found that it's not something specific to RX it was actually created in 1993 by Michael Golan and it was a patch for JDB version 4 at that time and apparently from what I gather from various emails Michael Golan had some principles and he didn't like JPL so he put his patch in public domain and JDB developers they had their own principles they required all the patches to be in JPL and they didn't like public domain so the patch didn't never get got into JDB so yeah Michael Golan didn't get his language in known and JDB didn't get this wonderful feature and I suffered for 25 years without dual and JDB so everybody wins but luckily developers in gen 2 they weren't that patient about JPL so I submitted the patch I ported JPL to JDB 6 and submitted to gen 2 which is what I'm using in my laptop and it was in gen 2 as distribution patch in the whole 2008 automatically applied and if anybody installed JDB on gen 2 which later JDB gen 2 moved to JDB 7 and the patch didn't apply anymore and I tried it didn't really apply it was a lot of changes in JDB 7 so again I forgot about it and last year I remember about it again and then I implemented dual completely from scratch in Python using JDB Python API so now it's a modular that can be loaded run time it doesn't depend on anything in JDB internals it doesn't need patching JDB doesn't compile in you just can download the Python model you can load it run time you can load it from JDB it will work even if you upgrade JDB because it only depends on documented JDB Python API and I hope they'll keep this stable so now what is actually dual what it can do so I think this picture is quite familiar to everyone who ever debugged anything in my JDB table list is a structure that contains all tables that are used by any particular scale query so if I want to see if I want to print it so I first print the first table then I print the second one then the third one and so on and so on until either I print the whole list or I get bored and with dual it can be done with just one command you tell dual to print the linked list and dual walks the list until it gets the null pointer and it prints every single element in the list and this is part this is extension of the dual to the dual is an extension of C syntax C expression syntax in a way and this is a dual extension of the syntax tells dual to traverse the linked list using the next global pointers so every link element must have this next global pointer and then it'll just walk the pointer and put in the table name for every element no no so I actually was going to explain the fundamentals later we're just starting from few examples but there's no pretty printer for this we're just a regular just a regular string and another example from the linked list this list is not longer so I don't think I just want to see how long it is and then this operator it tells me how many elements are in the linked list in a way and this is an example shows where I want to find whether this item is present in this link list or not yes sure enough it's present and it has number five in the list and one more example to show what it can do with arrays arrays are very easy you can you because you can use a range instead of any array index you can print the whole list the whole array there's just one command and it's a very common idiom to have an array that where you don't know the number of elements but you have some property on the last element to mark the end in this particular case the last element in the array has the name equals now so I use an open-ended range saying start from zero and go well at an infinitum but stop at zero and then it'll automatically go and it'll stop when the name equals zero this way I can print arrays where I don't know the length in a runs I'll show that later yeah and this is the one most important thing where the whole logic of dual is based upon so in see you can write an expression like one plus a hundred and then the one is is expression and a hundred is expression and the result of one plus hundred is another expression with the value of 101 and in dual every expression each hand can have many values instead of one you can have a list of one two three for example instead of hundred a hundred you can have many values then when you apply a plus plus is a regular see operator that only sub works on individual values it'll work on every possible value pair where first value is taken from the first operand and second value is taken from the other operand let's say if you have downloaded you can just type it in and you'll see this this very result and this works this is generalization works on every see operator like taking a subscript of an array or of a string there are two strings into in two subscripts so the square brackets will be applied four times to every combination there will be focus for at least this expression will have for result expression will have four values BC and EF so just a small generalization of the C syntax allowing an expression to return many values and because of that it's very easy to go from existing expression that you use in print in GDB to dual expressions in dual because this is how I would print a single element from the table option this is a structure it has an element called name so I just won't print the name I printed like this that's nothing fancy in here I would want to print many many I would simply replace the index with a range then I would print many elements at once because this is just a small expansion of scene of just more generalization of existing C syntax and the same works for linked list this is intentionally complex example because it's C so there's the reference in a pointer then it's casting because it's void pointed C it's not C++ then a couple of more de-references then I get a long path on my file system then I add something just to skip the beginning and get to the interesting part and if I want if I were want to print the whole list I would just need to extend it a little bit by specifying how to traverse the list and then I would get the whole list printed at once and this is works exactly as you would you might respect because in C the or with GDB printer print command it would take the value of this pointer then it would take the data member of this structure then cast and then so on and here this command with long arrow those two it would generate a list of values and then for every value it would do this one and then that one and then that one so it will work pretty much like this command but instead of one way there will be a list of values so and so and let's make a checkpoint so if somebody would want to leave the room right now this the one this the one important thing I would want you to remember so in dual the any expression can return many values and convention see apparatus they work with many values by that basically apply to every value in order and there are three ways in dual to generate those many values one way is using enumerations by simply specifying many expressions with comma one can also second way is using ranges to expressions with two dots between they can be also open ranges where either first boundary or the second boundary is emitted and that's also least traversal that I've just shown with linked list but it's not only for linked list because by combining those operators you can easily just as easy traverse traverse binary trees by saying that you need to start from root and you need to traverse two pointers not just one this is not a new operator just combined because all the operators can be combined just as easily in C as in C yes I'll I don't have example with the circular list I have example in the manual and I'll I'll mention circular is later I couldn't find an example of circular list inside my adb so I don't have this example so now a little bit more advanced but still useful operators the operator which I call until this is this one this was example I've already shown it means go from the zero to every element of the array and stop going when the name equals zero so this one number five would have had this null pointer in here that's why dual stopped iterating but an ngdb there's actually this similar thing when you can specify it and then something to print many arrays and there's some syntax thing that you put in the end in dual this is not something to put at the end it's a just normal operator which can be combined with any other operators operators just normally could be used in the yeah it could be used in the middle of the expression just the same table field array is it's an array of all fields of the table it's not a ray of structures like here it's a ray of pointers to structures and it's terminated with a null pointer so first I need to walk the whole array and stop at the null pointer and then for every element of the array I print the field name this is different from this one because here I apply it operator at the end but this is just to show this normal operator it could be used anywhere in the expression where it makes sense but in fact it's related to the question that was just asked this is a shortcut a simplified syntax the full syntax for this operator means shows that this here could be the second expression which and the iteration stops when this expression becomes true so I can walk the whole array and print the whole structures for every element and I need to stop when the name becomes zero that's how it stops the name being zero so you can put here an arbitrary expression and the walking down the array stop will stop when this expression becomes true this until operator is most commonly used with open-ended ranges but it can actually be used to do as to do a cyclic list because then you do again to error operator with to error with a long arrow and you tell it to stop when the end of the end of the list becomes the beginning so you can do so you can stop cyclic list this way then if gdb will print a screen full it will ask you can continue or not continue then you stop or you press control C if you disable that another useful feature is filters so in my adb in my school there's a concept of virtual fields it's fields in the table that are generated and the virtual field is different from a normal field because they have vehicle info pointer being non-zero so if I want to see all virtual fields in a table I would probably do something like this so I would print the whole array and I if I look in what fields vehicle info is not zero and if I look very careful at this slide I could see that it's second six and seventh but so that's a problem that first I don't really want to look very careful to look for minor difference in characters the second is there would be a hundred of fields with only two virtual I would probably miss that so what I do I put a question mark in here after the inequality operator and the comparison operator becomes a filter operator it works like kind of like a grab so if the result is false the row is not printed at all and if it's true then the result of the expression is printed so now I can be easily see this the row fields two six and seven they have non-zero vehicle info pointers and because this is just an expression it also doesn't have to be at the end I can stack embedded into another expression and print field names just as well by printing field name of the result of this expression because this is just an expression that has three results and I can use it by de-referencing the pointer and printing field names and back to the example with the table names you have seen this the dual prints it first it prints the first element of the link links the second one then it stops printing a very long path to the last element it prints this thing in double square brackets it's not just a way to have a shorter printouts this is actually a syntax in dual to specify that you want a specific value out of the list of values so I can just use it and print the third table and this is a very short example just to explain just to highlight how it works this is the least of five values I want the third value starting from zero so it's four and a practical example would be if I were want to print the last element of the very long link list I can just print expand the whole link list and here I can calculate the length of the link list minus one and this way I'll print just the last element without printing the whole thing so all those operators they be can be combined to produce other complex expressions and this is again example from the previous slide where I print the last element of the array and I want to show the operator curly braces if I wrap this one in curly braces I have them I I won't have the expression and here I have its value because curly braces they go by they go like braces but they also evaluate the result and print it in here so I can easily see what element in the array was found by the previous expression there are also aggregation operators the one that sums the value it's not like I said earlier it I wanted to calculate the length of the link list but it doesn't really calculate the length of the link list it it can be applied to any expression and it will return the number of values in this expression so here I do multiple value expression that works the whole link list and it returns all the elements in the link list then I apply the counter operator and it returns the number of elements in this expression this number of elements in the link list another one is sums all the numbers all the numbers from the all the values in the expression and it and it can be used if I want in my adb for example this structure is counts how many times a particular skill statement was executed and if I want to do a sum of how many times any case goes it was a good executed I can just do it with dual this way and then I come to the number 17 and this is not a complete description of dual there are other operators which are not as often used as those that I've already mentioned I mentioned them the essential purposes I used pretty much daily well some of them weekly and others that I didn't mention I use maybe never or maybe once a month but they came from the original original dual that was implemented by Michael Golan I tried to preserve the semantics and all the operators so it's all very useful I guess the first question is what licenses is the dual PY under now is a GPL I think it's busy as far as I remember you know yet busy three plus one of the reasons that you were mentioned earlier was it doesn't look pretty printers on the actual printed values so like in that link list yeah for example I don't know maybe something crazy excited to put vectors in link lists yeah so well I don't have in the slide but it uses no normal because it uses gdb python API and just returns gdb value so gdb prints them using whatever printer printers are installed for this particular value so this one works with three different interest right the original cc patch didn't this one works oh that's great I don't need to ask me the question how much is the implementation dependent on the language the c of c++ would it work with EDA or Pascal or the other languages supported by GED and if not is it complex to it it will work with any language but the dual syntax is C based so you'll need to use dual syntax in dual expressions whatever you use in when you do print command in GDB it's dual doesn't have anything to do with that it has a built-in parser that parses expressions according to dual language well it will work we just you just need to use Python you just need to use Pascal syntax when you do Pascal expression when you do print means you use syntax is syntax for Pascal for Pascal expressions when you use dual yes if you had a struct that had a pointer to like an array and then the struct had a field that was the number of elements yeah I didn't see a syntax that applied to that like where you could use an at sign condition no you don't need to use at sign condition for that you can just you can just use the range you can specify length here yeah it's everything here is an operator is two dots is the operator those two are expressions everything is an expression and they can be combined anyway you want yeah it'll check the name of the variable or name of the structure field depending on the yes if you're inside the structure is that output you've got there it looks very standard you've got the name of the value and then the value of the value that's that's that's non customizable right you've got to have no no no the only thing you have is curly braces is yeah the only thing if you put curly braces around something then you have its value in here instead of the original symbolic expression okay but I've copied the syntax from the from the original dual all right so you're you're you're able to do well almost original dual print the string in here I use gdb standard printers so I get I I get so the string is printed as a point like in here yeah well hash the counter operation hash slash it it does not count an elements in the array or anything it returns the number of values in the expression if I will put it in here it would return hundred because this expression has 100 values so first you need to you get an array then you need to to convert it to all values of the array by using square brackets and the range inside and then and then this one will turn how many values you got so you've got two types of expression here I guess you've got the expression with dual which tells it how to print and I'm assuming then that dual passes the actual expressions gdb's expression so any no no no not well it doesn't pass individual expressions it passes it will pass thd and then it'll use get the structure for this and then it'll get freely released member of the thd structure I'm just wondering how you could you know creative casting how that would work I mean say you've got a value and you want to cast it to another value and you know whether it'll it'll get it'll get gdb type object for the cast and then it'll cast the previous previous gdb value to this one this is actually what original dual didn't do it didn't do casting properly because there was syntax ambiguity and the way I've sold syntax ambiguity I just assume this a type I try to resolve it to type it doesn't go with type as a result is a dual expression yes yeah I've got this question so in a sense I've got it as a issue in github I didn't I didn't I didn't invest any effort into that I'm gonna be a little db I'm not particularly I don't know maybe if there will be many more requests I look into it I guess it's pretty it should be pretty sure to separate the parser from the gdb API stuff then it might be possible yes so that's that's some limitation of gdb Python API so I can do function calls like I can it can invoke normal functions it cannot invoke gdb built-in functions and it cannot invoke objects object methods because object methods and gdb built-in functions they are not callable when converted to gdb value so there's a bug report about that and there's not much activity around there no no I guess that was the main one you have a question you have a question could you please speak up louder change the display of this one no no because it's it's well it's designed it was designed to be to easily print and analyze structures it's not a man we should generate pretty reports out of your data so that's not much formatting of what you do with the data I guess I can do it have any plans to make it more extensive for example you can find your own special operator like the app operator which does something now so far the only thing I did it was not in the original view it was a plus generator but it's a parser region in our page of the spite and more than if you want to extend it you do something that you think is generally useful not only for you then do please submit a foolish work yeah thank you for the talk