././@PaxHeader 0000000 0000000 0000000 00000000034 00000000000 010212 x ustar 00 28 mtime=1675430767.9521296
guider-3.9.897/ 0000755 0000000 0000000 00000000000 14367205560 011740 5 ustar 00root root ././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1603118621.0
guider-3.9.897/LICENSE 0000644 0000000 0000000 00000043177 13743323035 012754 0 ustar 00root root GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
{description}
Copyright (C) {year} {fullname}
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
{signature of Ty Coon}, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.
././@PaxHeader 0000000 0000000 0000000 00000000034 00000000000 010212 x ustar 00 28 mtime=1675430767.9521296
guider-3.9.897/PKG-INFO 0000644 0000000 0000000 00000002063 14367205560 013036 0 ustar 00root root Metadata-Version: 2.1
Name: guider
Version: 3.9.897
Summary: Unified performance analyzer
Home-page: https://github.com/iipeace/guider
Author: Peace Lee
Author-email: iipeace5@gmail.com
License: GPL2
Download-URL: https://github.com/iipeace/guider/archive/master.zip
Keywords: guider,linux,analyzer,performance,profile,trace,kernel
Platform: UNKNOWN
Classifier: Environment :: Console
Classifier: Natural Language :: English
Classifier: Operating System :: Android
Classifier: Operating System :: MacOS
Classifier: Operating System :: Microsoft :: Windows
Classifier: Operating System :: POSIX :: Linux
Classifier: Programming Language :: Python
Classifier: Topic :: Software Development :: Debuggers
Classifier: Topic :: Software Development :: Embedded Systems
Classifier: Topic :: Software Development :: Testing
Classifier: Topic :: System :: Filesystems
Classifier: Topic :: System :: Monitoring
Classifier: Topic :: System :: Operating System Kernels :: Linux
Classifier: License :: OSI Approved :: GNU General Public License v2 (GPLv2)
License-File: LICENSE
UNKNOWN
././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1675410865.0
guider-3.9.897/README.md 0000664 0000000 0000000 00000357037 14367136661 013245 0 ustar 00root root [](https://travis-ci.org/iipeace/guider)
[](https://raw.githubusercontent.com/iipeace/guider/master/LICENSE)
[](https://scan.coverity.com/projects/iipeace-guider)
[](https://badge.fury.io/py/guider)
[](https://sourceforge.net/projects/guider/files/latest/download)
[](https://gitter.im/guiderchat/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)

Table of contents
=================
* [Guider](#Guider)
* [Output](#Output)
* [How to use](#How-to-use)
* [Build & Installation](#Build--Installation)
* [Kernel Configuration](#Kernel-Configuration)
* [Help](#Help)
Guider
=======
Guider is a comprehensive performance analysis tool designed to meet all your system performance needs.
With features like monitoring, profiling, tracing, visualization, control, logging, networking, testing, and utilities,
Guider provides you with everything you need to measure, analyze, and verify your system's performance.
Some of the key features of Guider include:
1. Accurate measurements: Guider provides measurements in units of count, time (in microseconds), and size (in bytes) for precise results.
2. Comprehensive functionality: Guider offers a range of functions for analysis and experimentation.
3. Detailed reports: Guider provides in-depth reports with as much information as possible.
4. Browser-based visualization: Guider outputs visualizations in SVG format for easy viewing in a browser.
5. Easy to use: Guider is designed to be simple and straightforward, with no need for installation or setup.
Guider supports a wide range of platforms based on the Linux kernel,
including distros like Ubuntu, CentOS, and RHEL, as well as Android, ccOS, webOS, Tizen, and AGL.
Limited support is also available for Windows and MacOS.
In terms of architecture, Guider can work on x86, x64, ARM, AArch64.
Output
=======
$ python3 guider/guider.py top -a
[Top Info] [Time: 4588832.570] [Inter: 1.0] [Ctxt: 314463] [Life: +0/-0] [IRQ: 26606] [Core: 40] [Task: 498/625] [Load: 0/0/0] [RAM: 125.7G] [Swap: 4.0G]
[Cycle: 8.3G / Inst: 5.7G / IPC: 0.69 / CacheMiss : 13.7M(23%) / BrcMiss: 25.7M(1%) / Clk: 38.7G / MinFlt: 358 / MajFlt: 0]
==========================================================================================================================================================
ID | CPU(Usr/Ker/Blk/IRQ)|MemAvl( Per/ User/Cache/Kern)| Swap( Per/ In/Out)| PgRclm | BlkRW | NrFlt | PrBlk | NrSIRQ | PgMlk | PgDirt | Network |
----------------------------------------------------------------------------------------------------------------------------------------------------------
Total | 10 %( 1 / 6 / 0 / 0 )|124649( 96/ 453/ 5690/1787)| 0( 0/ 0/ 0)| 0/0 | 0/0 | 0 | 0 | 15889 | 4616 | 20 | 2K/0 |
----------------------------------------------------------------------------------------------------------------------------------------------------------
Core/0 |100 %(66 /34 / 0 / 0 )|###################################################################| powersave | 0-0 | 24 C | 2874 Mhz [1171-3515]|
Core/1 | 7 %( 0 / 6 / 0 / 0 )|#### | powersave | 0-1 | 22 C | 2307 Mhz [1171-3515]|
Core/2 | 0 %( 0 / 0 / 0 / 0 )| | powersave | 0-2 | 23 C | 2165 Mhz [1171-3515]|
Core/3 | 0 %( 0 / 0 / 0 / 0 )| | powersave | 0-3 | 22 C | 2170 Mhz [1171-3515]|
Core/4 | 22 %( 0 /21 / 0 / 0 )|############## | powersave | 0-4 | 20 C | 2763 Mhz [1171-3515]|
Core/5 | 0 %( 0 / 0 / 0 / 0 )| | powersave | 0-8 | 24 C | 2160 Mhz [1171-3515]|
Core/6 | 33 %( 0 / 0 / 0 /32 )|###################### | powersave | 0-9 | 19 C | 2194 Mhz [1171-3515]|
Core/7 | 0 %( 0 / 0 / 0 / 0 )| | powersave | 0-10 | 17 C | 2160 Mhz [1171-3515]|
Core/8 | 0 %( 0 / 0 / 0 / 0 )| | powersave | 0-11 | 23 C | 2158 Mhz [1171-3515]|
Core/9 | 0 %( 0 / 0 / 0 / 0 )| | powersave | 0-12 | 18 C | 2164 Mhz [1171-3515]|
Core/10| 0 %( 0 / 0 / 0 / 0 )| | powersave | 1-0 | 21 C | 2907 Mhz [1171-3515]|
Core/11| 0 %( 0 / 0 / 0 / 0 )| | powersave | 1-1 | 18 C | 2903 Mhz [1171-3515]|
Core/12| 11 %( 9 / 1 / 0 / 0 )|####### | powersave | 1-2 | 22 C | 2927 Mhz [1171-3515]|
Core/13| 0 %( 0 / 0 / 0 / 0 )| | powersave | 1-3 | 17 C | 2904 Mhz [1171-3515]|
Core/14| 0 %( 0 / 0 / 0 / 0 )| | powersave | 1-4 | 21 C | 2903 Mhz [1171-3515]|
Core/15| 7 %( 0 / 6 / 0 / 0 )|#### | powersave | 1-8 | 19 C | 2912 Mhz [1171-3515]|
Core/16| 0 %( 0 / 0 / 0 / 0 )| | powersave | 1-9 | 24 C | 2925 Mhz [1171-3515]|
Core/17| 87 %( 0 /86 / 0 / 0 )|########################################################## | powersave | 1-10 | 24 C | 2907 Mhz [1171-3515]|
Core/18|100 %( 0 /100/ 0 / 0 )|###################################################################| powersave | 1-11 | 20 C | 2914 Mhz [1171-3515]|
Core/19| 0 %( 0 / 0 / 0 / 0 )| | powersave | 1-12 | 21 C | 2894 Mhz [1171-3515]|
==========================================================================================================================================================
Process ( PID/ PPID/ Nr/ Pri)| CPU(Usr/Ker/Dly)| VSS( RSS/Txt/Shr/Swp)| Blk( RD/ WR/NrFlt)| SID | USER | FD | LifeTime| Parent |
----------------------------------------------------------------------------------------------------------------------------------------------------------
screen ( 2451/ 1/ 1/C 0)| 100( 66/ 34/ 0)| 11( 6/ 0/ 2/ 0)| 0( -/ -/ 0)| 2451|peacel| 64|53d:00:22| systemd(1)|
yes (1341199/1340350/ 1/C 0)| 99( 0/ 99/ 0)| 5( 0/ 0/ 0/ 0)| 0( -/ -/ 0)| 2452|peacel| 64| 00:00:03| vi(1340350)|
kworker/u80: (1341030/ 2/ 1/C 0)| 90( 0/ 90/ 0)| 0( 0/ 0/ -/ -)| 0( -/ -/ 0)| -| root| 64| 00:15:46| kthreadd(2)|
kworker/u80: (1340705/ 2/ 1/C 0)| 26( 0/ 26/ 0)| 0( 0/ 0/ -/ -)| 0( -/ -/ 0)| -| root| 64| 02:04:59| kthreadd(2)|
kworker/u80: (1340966/ 2/ 1/C 0)| 21( 0/ 21/ 0)| 0( 0/ 0/ -/ -)| 0( -/ -/ 0)| -| root| 64| 00:20:56| kthreadd(2)|
[ TOTAL ]| 344.0( 72/ 271)|RSS: 1G / Swp: 0)| 0.0( -/ -/ 0)| Yld: -| Prmt: -| Task: 498|
----------------------------------------------------------------------------------------------------------------------------------------------------------
[Z]bash ( 820918/ 820917/ 1/C 0)| 0( 0/ 0/ -)| 0( 0/ 0/ 0/ -)| 0( -/ -/ 0)| -| -| -| 3d:06:10| tmux: server(820917)|
----------------------------------------------------------------------------------------------------------------------------------------------------------
>>>
$ python3 guider/guider.py top -R 5 -o
$ cat guider.out
[Top Summary Info]
==========================================================================================================================================================
IDX | Interval | CPU | Avl/User/Cache | BlkRW | Blk | SWAP | NrPgRclm | NrFlt | NrCtx | NrIRQ | NrTask | Core | Network |
==========================================================================================================================================================
1 | START - 497231.500 | 98 | 124442/962/3854 | 0/0 | 0 | 0 | 0/0 | 0 | 631 | 10660 | 482/701 | 40 | 2K/156 |
2 | 497231.500 - 497232.520 | 98 | 124440/963/3854 | 0/0 | 0 | 0 | 0/0 | 0 | 646 | 10506 | 482/701 | 40 | 1K/104 |
3 | 497232.520 - 497233.540 | 98 | 124440/964/3854 | 0/0 | 0 | 0 | 0/0 | 0 | 741 | 10562 | 482/701 | 40 | 2K/104 |
4 | 497233.540 - 497234.570 | 98 | 124440/964/3854 | 0/0 | 0 | 0 | 0/0 | 0 | 629 | 10489 | 482/701 | 40 | 1K/104 |
5 | 497234.570 - 497235.590 | 98 | 124440/964/3854 | 0/0 | 0 | 0 | 0/0 | 0 | 699 | 10602 | 482/701 | 40 | 2K/208 |
----------------------------------------------------------------------------------------------------------------------------------------------------------
[Top CPU Info] (Unit: %)
==========================================================================================================================================================
COMM ( PID / PPID / Nr / Pri)| Min/Avg/Max | 1 2 3 4 5
==========================================================================================================================================================
[CPU] ( -/ -/ -/ -)| 98/98.0/98 | 98 98 98 98 98
----------------------------------------------------------------------------------------------------------------------------------------------------------
FahCore_a8 ( 55469/ 55465/ 41/C 19)| 384/387.0/389| 384 3898 3898 3860 3883
----------------------------------------------------------------------------------------------------------------------------------------------------------
guider ( 55767/ 9591/ 1/C 0)| 1/1.6/3 | 1 1 2 3 1
----------------------------------------------------------------------------------------------------------------------------------------------------------
[Top RSS Info] (Unit: MB)
==========================================================================================================================================================
COMM ( PID / PPID / Nr / Pri)| Max | 1 2 3 4 5
==========================================================================================================================================================
[FREE/MIN] ( -/ -/ -/ -)|124440 | 124442 124440 124440 124440 124440
----------------------------------------------------------------------------------------------------------------------------------------------------------
FahCore_a8 ( 55469/ 55465/ 41/C 19)| 548 | 548 548 548 548 548
----------------------------------------------------------------------------------------------------------------------------------------------------------
guider ( 55767/ 9591/ 1/C 0)| 34 | 33 34 34 34 34
----------------------------------------------------------------------------------------------------------------------------------------------------------
>>>
$ python3 guider/guider.py ttop
[Top Info] [Time: 194025.590] [Interval: 1.0] [Ctxt: 4995] [Life: +0/-0] [OOM: 0] [IRQ: 1879] [Core: 8] [Task: 333/1188] [Load: 3.1/1.9/0.9] [RAM: 62.8G]
==========================================================================================================================================================
ID | CPU(Usr/Ker/Blk/IRQ)| Avl(Diff/ User/Cache/Kern)| Swap(Diff/ In/Out)| PgRclm | BlkRW | NrFlt | PrBlk | NrSIRQ | PgMlk | PgDrt | Network |
----------------------------------------------------------------------------------------------------------------------------------------------------------
Total | 3 %( 1 / 0 /23 / 0 )|59874( -3/ 3110/15153/ 355)| 0( 0/ 0/ 0)| 0/0 | 0/5 | 0 | 2 | 313 | 1607 | 939290 | 0/0 |
==========================================================================================================================================================
Thread ( TID/ PID/ Nr/ Pri)| CPU(Usr/Ker/Dly)| VSS(RSS/Txt/Shr/Swp)| Blk( RD/ WR/NrFlt)| Yld | Prmt | FD | LifeTime| Process |
----------------------------------------------------------------------------------------------------------------------------------------------------------
guider ( 8160/ 8160/ 1/C 0)| 3( 2/ 0/ 0)| 66( 33/ 2/ 6/ 0)| 0( -/ -/ 0)| 1| 0|2048| 00:00:02| guider(8160)|
gnome-terminal- ( 4864/ 4864/ 4/C 0)| 1( 0/ 0/ -)| 627( 57/ 0/ 40/ 0)| 0( -/ -/ 0)| -| -| 128| 2d:05:52|gnome-terminal-(4864)|
Xorg ( 1525/ 1525/ 2/C 0)| 1( 0/ 0/ -)| 431( 84/ 0/ 48/ 0)| 0( -/ -/ 0)| -| -| 128| 2d:05:53| Xorg(1525)|
[ TOTAL ]| 5( 2/ 0)|RSS: 174M / Swp: 0)| 0.0( -/ -/ 0)| Yld: 1| Prmt: 0| Task: 3|
----------------------------------------------------------------------------------------------------------------------------------------------------------
[D]kworker/u16:0 ( 7784/ 7784/ 1/C 0)| 0( 0/ 0/ -)| 0( 0/ 0/ -/ -)| 0( -/ -/ 0)| -| -| -| 00:07:07| -|
[D]pool ( 8024/ 2450/ 13/C 0)| 0( 0/ 0/ -)| 1025( 82/ 1/ -/ -)| 0( -/ -/ 0)| -| -| -| 00:04:31| -|
[D]usb-storage ( 7825/ 7825/ 1/C 0)| 0( 0/ 0/ -)| 0( 0/ 0/ -/ -)| 0( -/ -/ 0)| -| -| -| 00:06:38| -|
----------------------------------------------------------------------------------------------------------------------------------------------------------
>>>
# python3 guider/guider.py utop -g yes -H
[Top Usercall Info] [Time: 82094.260000] [Interval: 1.001784] [NrSamples: 955] [yes(7202): 28%(Usr/27%+Sys/0%)] [SampleTime: 0.000100]
==========================================================================================================================================================
Usage | Function [Path]
==========================================================================================================================================================
35.6% | _IO_file_xsputn@GLIBC_2.17 [/lib/libc-2.24.so]
100.0% | <- fputs_unlocked@GLIBC_2.17[/lib/libc-2.24.so] <- ??[/usr/bin/yes.coreutils] <- __libc_start_main@GLIBC_2.17[/lib/libc-2.24.so]
----------------------------------------------------------------------------------------------------------------------------------------------------------
17.8% | fputs_unlocked@GLIBC_2.17 [/lib/libc-2.24.so]
100.0% | <- ??[/usr/bin/yes.coreutils] <- __libc_start_main@GLIBC_2.17[/lib/libc-2.24.so]
----------------------------------------------------------------------------------------------------------------------------------------------------------
16.1% | __libc_start_main@GLIBC_2.17 [/lib/libc-2.24.so]
----------------------------------------------------------------------------------------------------------------------------------------------------------
14.7% | memcpy@GLIBC_2.17 [/lib/libc-2.24.so]
100.0% | <- _IO_file_xsputn@GLIBC_2.17[/lib/libc-2.24.so] <- fputs_unlocked@GLIBC_2.17[/lib/libc-2.24.so] <- ??[/usr/bin/yes.coreutils]
<- __libc_start_main@GLIBC_2.17[/lib/libc-2.24.so]
----------------------------------------------------------------------------------------------------------------------------------------------------------
12.3% | strlen@GLIBC_2.17 [/lib/libc-2.24.so]
100.0% | <- fputs_unlocked@GLIBC_2.17[/lib/libc-2.24.so] <- ??[/usr/bin/yes.coreutils] <- __libc_start_main@GLIBC_2.17[/lib/libc-2.24.so]
----------------------------------------------------------------------------------------------------------------------------------------------------------
3.0% | _IO_file_write@GLIBC_2.17 [/lib/libc-2.24.so]
100.0% | <- ??[/lib/libc-2.24.so] <- _IO_do_write@GLIBC_2.17[/lib/libc-2.24.so] <- _IO_file_xsputn@GLIBC_2.17[/lib/libc-2.24.so]
<- fputs_unlocked@GLIBC_2.17[/lib/libc-2.24.so] <- ??[/usr/bin/yes.coreutils]
<- __libc_start_main@GLIBC_2.17[/lib/libc-2.24.so]
----------------------------------------------------------------------------------------------------------------------------------------------------------
>>>
# python3 guider/guider.py utop -g node -H -q JITSYM
[Top Usercall Info] [Time: 7249986.900] [Interval: 1.015] [Samples: 442] [SYS: 2%/120G] [node(1068318): 50%(U46%+S3%)/897M] [guider(1068338): 53%/256M] [Freq:
==========================================================================================================================================================
Usage | Function [PATH]
==========================================================================================================================================================
18.6% | write@GLIBC_2.28 [/usr/lib/x86_64-linux-gnu/libpthread-2.31.so]
100.0% | <- 0x13250[/usr/lib/x86_64-linux-gnu/libuv.so.1.0.0] <- uv_fs_write[/usr/lib/x86_64-linux-gnu/libuv.so.1.0.0]
<- 0x573090[/usr/lib/x86_64-linux-gnu/libnode.so.64] <- JIT[JIT] <- LazyCompile:*writeSync fs.js:551[JIT]
<- Builtin:ArgumentsAdaptorTrampoline[JIT] <- LazyCompile:*writeOrBuffer _stream_writable.js:365[JIT]
<- LazyCompile:*log console.js:199[JIT] <- Builtin:ArgumentsAdaptorTrampoline[JIT] <- Builtin:JSEntryTrampoline[JIT] <- JIT[JIT]
<- 0xab0110[/usr/lib/x86_64-linux-gnu/libnode.so.64] <- 0xab0720[/usr/lib/x86_64-linux-gnu/libnode.so.64]
<- v8::internal::Execution::Call(v8::internal::Isolate*, v8::internal::Handle, v8::internal::Handle, v8::Local, int, v8::Local*)[/usr/lib/x86_64-linux-gnu/libnode.so.64]
<- 0x630d40[/usr/lib/x86_64-linux-gnu/libnode.so.64] <- JIT[JIT] <- LazyCompile:* /home/peacelee/test/test.js:1[JIT]
<- Builtin:InterpreterEntryTrampoline[JIT] <- Builtin:JSEntryTrampoline[JIT] * 8 <- JIT[JIT]
<- 0xab0110[/usr/lib/x86_64-linux-gnu/libnode.so.64] <- 0xab0720[/usr/lib/x86_64-linux-gnu/libnode.so.64]
<- v8::internal::Execution::Call(v8::internal::Isolate*, v8::internal::Handle, v8::internal::Handle, v8::Local, int, v8::Local*)[/usr/lib/x86_64-linux-gnu/libnode.so.64]
<- 0x52cae0[/usr/lib/x86_64-linux-gnu/libnode.so.64]
<- node::LoadEnvironment(node::Environment*)[/usr/lib/x86_64-linux-gnu/libnode.so.64]
<- node::Start(v8::Isolate*, node::IsolateData*, std::vector, std::allocator
----------------------------------------------------------------------------------------------------------------------------------------------------------
3.8% | LazyCompile:*writeOrBuffer _stream_writable.js:365 [JIT]
64.7% | <- LazyCompile:*log console.js:199[JIT] <- Builtin:ArgumentsAdaptorTrampoline[JIT] <- Builtin:JSEntryTrampoline[JIT] <- JIT[JIT]
<- 0xab0110[/usr/lib/x86_64-linux-gnu/libnode.so.64] <- 0xab0720[/usr/lib/x86_64-linux-gnu/libnode.so.64]
<- v8::internal::Execution::Call(v8::internal::Isolate*, v8::internal::Handle, v8::internal::Handle, v8::Local, int, v8::Local*)[/usr/lib/x86_64-linux-gnu/libnode.so.64]
<- 0x630d40[/usr/lib/x86_64-linux-gnu/libnode.so.64] <- JIT[JIT] <- LazyCompile:* /home/peacelee/test/test.js:1[JIT]
<- Builtin:InterpreterEntryTrampoline[JIT] <- Builtin:JSEntryTrampoline[JIT] * 8 <- JIT[JIT]
<- 0xab0110[/usr/lib/x86_64-linux-gnu/libnode.so.64] <- 0xab0720[/usr/lib/x86_64-linux-gnu/libnode.so.64]
<- v8::internal::Execution::Call(v8::internal::Isolate*, v8::internal::Handle, v8::internal::Handle, v8::Local, int, v8::Local*)[/usr/lib/x86_64-linux-gnu/libnode.so.64]
<- 0x52cae0[/usr/lib/x86_64-linux-gnu/libnode.so.64]
<- node::LoadEnvironment(node::Environment*)[/usr/lib/x86_64-linux-gnu/libnode.so.64]
<- node::Start(v8::Isolate*, node::IsolateData*, std::vector, std::allocator
----------------------------------------------------------------------------------------------------------------------------------------------------------
>>>
# python3 guider/guider.py systop -g yes -H
[Top Syscall Info] [Time: 82043.230000] [Interval: 1.000940] [NrSamples: 634] [yes(7202): 5%(Usr/4%+Sys/0%)]
==========================================================================================================================================================
Usage | Function [Count]
==========================================================================================================================================================
100.0% | write [Cnt: 634, Tot: 0.830203, Avg: 0.001309, Max: 0.005875, Err: 0]
100.0% | <- ??[/lib/libc-2.24.so] <- _IO_file_write@GLIBC_2.17[/lib/libc-2.24.so] <- ??[/lib/libc-2.24.so]
<- _IO_do_write@GLIBC_2.17[/lib/libc-2.24.so] <- _IO_file_xsputn@GLIBC_2.17[/lib/libc-2.24.so]
<- fputs_unlocked@GLIBC_2.17[/lib/libc-2.24.so] <- ??[/usr/bin/yes.coreutils]
<- __libc_start_main@GLIBC_2.17[/lib/libc-2.24.so]
----------------------------------------------------------------------------------------------------------------------------------------------------------
>>>
# python3 guider/guider.py btop -g a.out -H
[Top Breakcall Info] [Time: 4542869.660] [Interval: 1.001] [NrSamples: 994] [a.out(1219772): 7%(Usr/0%+Sys/6%)] [guider(1219775): 97%]
==========================================================================================================================================================
Usage | Function [PATH]
==========================================================================================================================================================
16.7% | __mempcpy_sse2_unaligned_erms [/lib/x86_64-linux-gnu/libc-2.31.so] >>
# python3 guider/guider.py pytop -g iotop -H
[Top Pycall Info] [Time: 7469667.000] [Interval: 1.003] [NrSamples: 283] [iotop(2943070): 13%(Usr/10%+Sys/2%)] [guider(2943073): 53%] [SampleRate: 0.001]
==========================================================================================================================================================
Usage | Function [PATH]
==========================================================================================================================================================
56.9% | WAIT(poll@GLIBC_2.2.5) [/usr/lib/x86_64-linux-gnu/libc-2.31.so]
100.0% | <- run[/usr/lib/python3/dist-packages/iotop/ui.py] <- run_iotop_window[/usr/lib/python3/dist-packages/iotop/ui.py]
<- wrapper[/usr/lib/python3.8/curses/__init__.py] <- run_iotop[/usr/lib/python3/dist-packages/iotop/ui.py]
<- [/usr/lib/python3/dist-packages/iotop/ui.py] <- main[/usr/lib/python3/dist-packages/iotop/ui.py]
<- [/usr/sbin/iotop]
----------------------------------------------------------------------------------------------------------------------------------------------------------
10.2% | parse_proc_pid_status [/usr/lib/python3/dist-packages/iotop/data.py]
100.0% | <- get_cmdline[/usr/lib/python3/dist-packages/iotop/data.py] <- format[/usr/lib/python3/dist-packages/iotop/ui.py]
<- get_data[/usr/lib/python3/dist-packages/iotop/ui.py] <- refresh_display[/usr/lib/python3/dist-packages/iotop/ui.py]
<- run[/usr/lib/python3/dist-packages/iotop/ui.py] <- run_iotop_window[/usr/lib/python3/dist-packages/iotop/ui.py]
<- wrapper[/usr/lib/python3.8/curses/__init__.py] <- run_iotop[/usr/lib/python3/dist-packages/iotop/ui.py]
<- [/usr/lib/python3/dist-packages/iotop/ui.py] <- main[/usr/lib/python3/dist-packages/iotop/ui.py]
<- [/usr/sbin/iotop]
----------------------------------------------------------------------------------------------------------------------------------------------------------
4.6% | read@GLIBC_2.26 [/usr/lib/x86_64-linux-gnu/libc-2.31.so]
76.9% | <- parse_proc_pid_status[/usr/lib/python3/dist-packages/iotop/data.py] <- get_cmdline[/usr/lib/python3/dist-packages/iotop/data.py]
<- format[/usr/lib/python3/dist-packages/iotop/ui.py] <- get_data[/usr/lib/python3/dist-packages/iotop/ui.py]
<- refresh_display[/usr/lib/python3/dist-packages/iotop/ui.py] <- run[/usr/lib/python3/dist-packages/iotop/ui.py]
<- run_iotop_window[/usr/lib/python3/dist-packages/iotop/ui.py] <- wrapper[/usr/lib/python3.8/curses/__init__.py]
<- run_iotop[/usr/lib/python3/dist-packages/iotop/ui.py] <- [/usr/lib/python3/dist-packages/iotop/ui.py]
<- main[/usr/lib/python3/dist-packages/iotop/ui.py] <- [/usr/sbin/iotop]
23.1% | <- get_cmdline[/usr/lib/python3/dist-packages/iotop/data.py] <- format[/usr/lib/python3/dist-packages/iotop/ui.py]
<- get_data[/usr/lib/python3/dist-packages/iotop/ui.py] <- refresh_display[/usr/lib/python3/dist-packages/iotop/ui.py]
<- run[/usr/lib/python3/dist-packages/iotop/ui.py] <- run_iotop_window[/usr/lib/python3/dist-packages/iotop/ui.py]
<- wrapper[/usr/lib/python3.8/curses/__init__.py] <- run_iotop[/usr/lib/python3/dist-packages/iotop/ui.py]
<- [/usr/lib/python3/dist-packages/iotop/ui.py] <- main[/usr/lib/python3/dist-packages/iotop/ui.py]
<- [/usr/sbin/iotop]
----------------------------------------------------------------------------------------------------------------------------------------------------------
4.2% | format [/usr/lib/python3/dist-packages/iotop/ui.py]
100.0% | <- get_data[/usr/lib/python3/dist-packages/iotop/ui.py] <- refresh_display[/usr/lib/python3/dist-packages/iotop/ui.py]
<- run[/usr/lib/python3/dist-packages/iotop/ui.py] <- run_iotop_window[/usr/lib/python3/dist-packages/iotop/ui.py]
<- wrapper[/usr/lib/python3.8/curses/__init__.py] <- run_iotop[/usr/lib/python3/dist-packages/iotop/ui.py]
<- [/usr/lib/python3/dist-packages/iotop/ui.py] <- main[/usr/lib/python3/dist-packages/iotop/ui.py]
<- [/usr/sbin/iotop]
----------------------------------------------------------------------------------------------------------------------------------------------------------
>>>
# python3 guider/guider.py ftop -g nginx
[Top File Info] [Time: 497555.620] [Proc: 41] [FD: 2,047] [File: 87] [CPU: 95%(Usr:54%/Sys:41%)] (Unit: %/MB/NR)
==========================================================================================================================================================
Process ( ID / Pid / Nr / Pri)| FD | Path |
----------------------------------------------------------------------------------------------------------------------------------------------------------
nginx ( 1348/ 1333/ 1/C 0)| 49| SOCKET: 42 NORMAL: 3 DEVICE: 2 EVENT: 2 PIPE: 0 PROC: 0 |
| 49| /var/log/nginx/error.log (0, O_WRONLY|O_APPEND|O_CLOEXEC) |
| 48| socket:[32124] |
| 37| socket:[32102] |
| 36| anon_inode:[eventfd] |
| 35| anon_inode:[eventpoll] |
| 34| socket:[32073] |
| 8| socket:[32074] |
| 7| socket:[20935] |
| 6| socket:[20934] (TCP:0.0.0.0:80/LISTEN) |
| 5| /var/log/nginx/access.log (0, O_WRONLY|O_APPEND|O_CLOEXEC) |
| 3| socket:[32046] |
| 2| /var/log/nginx/error.log (0, O_WRONLY) |
| 1| /dev/null (0, O_RDWR) |
| 0| /dev/null (0, O_RDWR) |
----------------------------------------------------------------------------------------------------------------------------------------------------------
>>>
# python3 guider/guider.py stacktop -g syslog
[Top Info] [Time: 7176163.830] [Interval: 1.0] [Ctxt: 2914] [Life: +13/-12] [IRQ: 5103] [Core: 24] [Task: 328/435] [RAM: 63876] [Swap: 65491] (Unit: %/MB/NR)
[Cycle: 2G / Inst: 3G / IPC: 1.34 / CacheMiss: 6M(34%) / BranchMiss: 4M(0%) / Clock: 23G / MinFlt: 53,257 / MajFlt: 0]
==========================================================================================================================================================
ID | CPU (Usr/Ker/Blk/IRQ)| Mem (Diff/ User/Cache/Kern)| Swap (Diff/ I/O )|NrPgRclm | BlkRW | NrFlt | NrBlk | NrSIRQ | NrMlk | NrDrt | Network |
----------------------------------------------------------------------------------------------------------------------------------------------------------
Total | 6 %( 3 / 1 / 0 / 0 )| 4913(-204/ 974/56824/1165)| 0 ( 0 / 0/0 )| 0/0 | 0/42 | 0 | 0 | 3713 | 0 | 90901 | 2K/13K |
==========================================================================================================================================================
Thread ( TID/ PID/ Nr/ Pri)| CPU(Usr/Ker/Dly)| Mem(RSS/Txt/Shr/Swp)| Blk( RD / WR /NrFlt)| Yld | Prmt | FD | LifeTime| WaitChannel |
----------------------------------------------------------------------------------------------------------------------------------------------------------
rsyslogd ( 2702/ 2702/ 4/C 0)| 0( 0/ 0/ -)| 244( 5/ 0/ 2/ 0)| 0( -/ -/ 0)| 0| 0| 64| 1K:22:40|poll_schedule_timeout|
100% | poll_schedule_timeout+0x43/0x70 <- do_select+0x711/0x7f0 <- core_sys_select+0x196/0x280 <-
SyS_select+0xa6/0xe0 <- entry_SYSCALL_64_fastpath+0x1a/0xa5
----------------------------------------------------------------------------------------------------------------------------------------------------------
rsyslogd ( 2779/ 2702/ 4/C 0)| 0( 0/ 0/ -)| 244( 5/ 0/ 2/ 0)| 0( -/ -/ 0)| 0| 0| 64| 1K:22:40|poll_schedule_timeout|
100% | poll_schedule_timeout+0x43/0x70 <- do_select+0x711/0x7f0 <- core_sys_select+0x196/0x280 <-
SyS_select+0xa6/0xe0 <- entry_SYSCALL_64_fastpath+0x1a/0xa5
----------------------------------------------------------------------------------------------------------------------------------------------------------
rsyslogd ( 2780/ 2702/ 4/C 0)| 0( 0/ 0/ 0)| 244( 5/ 0/ 2/ 0)| 0( -/ -/ 0)| 116| 0| 64| 1K:22:40| do_syslog |
99% | do_syslog+0x446/0x4c0 <- kmsg_read+0x3f/0x50 <- proc_reg_read+0x3d/0x60 <- __vfs_read+0x23/0x110 <-
vfs_read+0x91/0x130 <- SyS_read+0x41/0xa0 <- entry_SYSCALL_64_fastpath+0x1a/0xa5
----------------------------------------------------------------------------------------------------------------------------------------------------------
>>>
# python3 guider/guider.py ptop -g yes
[Top Info] [Time: 7181955.420] [Interval: 1.0] [Ctxt: 121] [Life: +0/-0] [IRQ: 1947] [Core: 24] [Task: 317/424] [RAM: 63876] [Swap: 65491] (Unit: %/MB/NR)
==========================================================================================================================================================
ID | CPU (Usr/Ker/Blk/IRQ)| Mem (Diff/ User/Cache/Kern)| Swap (Diff/ I/O )|NrPgRclm | BlkRW | NrFlt | NrBlk | NrSIRQ | NrMlk | NrDrt | Network |
----------------------------------------------------------------------------------------------------------------------------------------------------------
Total | 5 %( 4 / 0 / 0 / 0 )| 3783( 0/ 875/58078/1140)| 0 ( 0 / 0/0 )| 0/0 | 0/0 | 0 | 0 | 2023 | 0 | 0 | 1K/3K |
==========================================================================================================================================================
Process ( PID/ PPID/ Nr/ Pri)| CPU(Usr/Ker/Dly)| Mem(RSS/Txt/Shr/Swp)| Blk( RD / WR /NrFlt)| Yld | Prmt | FD | LifeTime| WaitChannel |
----------------------------------------------------------------------------------------------------------------------------------------------------------
yes (22371/ 9085/ 1/R 90)| 99( 99/ 0/ 0)| 8( 0/ 0/ 0/ 0)| 0( -/ -/ 0)| 0| 0| 256| 1:34:11| RUNNING |
| [Cycle: 2G / Inst: 6G / IPC: 2.82 / CacheMiss: 11K(98%) / BranchMiss: 26K(0%) / Clock: 972M / MinFlt: 0 / MajFlt: 0]
----------------------------------------------------------------------------------------------------------------------------------------------------------
>>>
# python3 guider/guider.py mtop
[Top Info] [Time: 1144292.910] [Inter: 1.0] [Ctxt: 739] [Life: +0/-0] [IRQ: 10740] [Core: 40] [Task: 509/725] [Load: 38/38/38] [RAM: 125.7G] [Swap: 4.0G]
[N0-DMA > diff: 0 / free: 15.5M / high: 32.0K / low: 20.0K / managed: 15.5M / min: 8.0K / present: 15.6M / spanned: 16.0M ]
[N0-DMA32 > diff: 0 / free: 1.9G / high: 4.6M / low: 2.8M / managed: 1.9G / min: 956.0K / present: 1.9G / spanned: 4.0G ]
[N0-Device > diff: 0 / free: 0 / high: 0 / low: 0 / managed: 0 / min: 0 / present: 0 / spanned: 0 ]
[N0-Movable > diff: 0 / free: 0 / high: 0 / low: 0 / managed: 0 / min: 0 / present: 0 / spanned: 0 ]
[N0-Normal > diff: -3.9M / free: 113.4G / high: 318.7M / low: 191.9M / managed: 123.9G / min: 65.1M / present: 126.0G / spanned: 126.0G ]
==========================================================================================================================================================
ID | CPU(Usr/Ker/Blk/IRQ)| Avl( Per/ User/Cache/Kern)| Swap( Per/ In/Out)| PgRclm | BlkRW | NrFlt | PrBlk | NrSIRQ | PgMlk | PgDrt | Network |
----------------------------------------------------------------------------------------------------------------------------------------------------------
Total | 98 %(97 / 0 / 0 / 0 )|12417( 96/ 1117/ 7915/1739)| 0( 0/ 0/ 0)| 0/0 | 0/0 | 0 | 0 | 12975 | 4613 | 67 | 2K/52 |
==========================================================================================================================================================
Process ( PID/ PPID/ Nr/ Pri)| CPU(Usr/Ker/Dly)| Mem(RSS/Txt/Shr/Swp)| Blk( RD / WR /NrFlt)| Yld | Prmt | FD | LifeTime| WaitChannel |
----------------------------------------------------------------------------------------------------------------------------------------------------------
FahCore_a8 ( 214159/ 214155/ 41/C 19)|3792(3791/ 0/ -)|3219( 548/ 14/ 13/ 0)| 0( -/ -/ 0)| 1197|fahcli| 64| 00:20:54|FAHCoreWrapper(214155|
MEM(STACK/1) | VSS: 132.0K / RSS: 48.0K / PSS: 48.0K / SWAP: 0 / HUGE: 0 / LOCK: 0 / SDRT: 0 / PDRT: 48.0K|
MEM(FILE/6) | VSS: 20.4M / RSS: 13.2M / PSS: 10.7M / SWAP: 0 / HUGE: 0 / LOCK: 0 / SDRT: 0 / PDRT: 92.0K|
MEM(ETC/3) | VSS: 20.0K / RSS: 4.0K / PSS: 0 / SWAP: 0 / HUGE: 0 / LOCK: 0 / SDRT: 0 / PDRT: 0|
MEM(ANON/165) | VSS: 3.1G / RSS: 539.7M / PSS: 539.7M / SWAP: 0 / HUGE: 0 / LOCK: 0 / SDRT: 0 / PDRT: 539.7M|
MEM(SUM) | VmPeak: 4.0G, VmHWM: 548.6M, VmData: 948.2M, HugetlbPages: 0, RssAnon: 535.5M, RssFile: 13.2M, RssShmem: 0 |
----------------------------------------------------------------------------------------------------------------------------------------------------------
>>>
# python3 guider/guider.py ntop
[Top Info] [Time: 186473.960] [Interval: 1.0] [Ctxt: 7865] [Life: +0/-0] [OOM: 0] [IRQ: 4229] [Core: 8] [Task: 328/1171] [Load: 0.5/0.3/0.3] [RAM: 62.8G]
==========================================================================================================================================================
ID | CPU(Usr/Ker/Blk/IRQ)| Avl(Diff/ User/Cache/Kern)| Swap(Diff/ In/Out)| PgRclm | BlkRW | NrFlt | PrBlk | NrSIRQ | PgMlk | PgDrt | Network |
----------------------------------------------------------------------------------------------------------------------------------------------------------
Total | 1 %( 0 / 0 / 0 / 0 )|59939( -2/ 3054/ 6429/ 350)| 0( 0/ 0/ 0)| 0/0 | 0/0 | 0 | 0 | 1661 | 1607 | 343 | 652K/9K |
==========================================================================================================================================================
Network | Receive | Transfer |
----------------------------------------------------------------------------------------------------------------------------------------------------------
Dev | IP | Size | Packet | Error | Drop | Multicast | Size | Packet | Error | Drop | Multicast |
==========================================================================================================================================================
docker0 | 166.104.101.26 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
eno1 | 166.104.101.1 | 665.9K | 475 | 0 | 0 | 1 | 12.0K | 168 | 0 | 0 | 0 |
enx201601190a25 | 166.104.101.27 | 48 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
lo | 127.0.0.1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
virbr0 | | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
virbr0-nic | | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
[ TOTAL ] | | 666.0K | 476 | 0 | 0 | 1 | 12.0K | 168 | 0 | 0 | 0 |
==========================================================================================================================================================
>>>
# python3 guider/guider.py disktop
[Top Info] [Time: 262411.830] [Inter: 1.0] [Ctxt: 802] [Life: +0/-0] [IRQ: 10675] [Core: 40] [Task: 481/700] [Load: 38/38/38] [RAM: 125.7G] [Swap: 4.0G]
==========================================================================================================================================================
ID | CPU(Usr/Ker/Blk/IRQ)| Avl( Per/ User/Cache/Kern)| Swap( Per/ In/Out)| PgRclm | BlkRW | NrFlt | PrBlk | NrSIRQ | PgMlk | PgDrt | Network |
----------------------------------------------------------------------------------------------------------------------------------------------------------
Total | 98 %(97 / 0 / 0 / 0 )|124431( 96/ 994/ 3531/1733)| 0( 0/ 0/ 0)| 0/0 | 0/0 | 0 | 0 | 11620 | 4613 | 70 | 1K/0 |
==========================================================================================================================================================
DEV |BUSY| AVQ | READ | WRITE | FREE( DIFF)|USAGE| TOTAL | AVF | FS | MountPoint |
----------------------------------------------------------------------------------------------------------------------------------------------------------
/dev/sda2 | 0%| 0| 0| 0| 670.6G( 0)| 28%| 937.4G| 57.6M| ext4 | / |
/dev/loop4 | 0%| 0| 0| 0| 0( 0)| 100%| 30.0M| 0|squashfs| /snap/snapd/9279 |
/dev/loop5 | 0%| 0| 0| 0| 0( 0)| 100%| 70.0M| 0|squashfs| /snap/lxd/16922 |
/dev/sda1 | 0%| 0| 0| 0| 503.0M( 0)| 1%| 510.0M| 0| vfat | /boot/efi |
/dev/loop1 | 0%| 0| 0| 0| 0( 0)| 100%| 55.0M| 0|squashfs| /snap/core18/1885 |
/dev/loop2 | 0%| 0| 0| 0| 0( 0)| 100%| 70.0M| 0|squashfs| /snap/lxd/16894 |
/dev/loop0 | 0%| 0| 0| 0| 0( 0)| 100%| 55.0M| 0|squashfs| /snap/core18/1880 |
/dev/loop3 | 0%| 0| 0| 0| 0( 0)| 100%| 30.0M| 0|squashfs| /snap/snapd/8790 |
/run/snapd/ns | 0%| 0| 0| 0| 12.6G( 0)| 0%| 12.6G| 15.7M| tmpfs | /run/snapd/ns |
/run/user/1004 | 0%| 0| 0| 0| 12.6G( 0)| 0%| 12.6G| 15.7M| tmpfs | /run/user/1004 |
/sys/fs/cgroup | 0%| 0| 0| 0| 62.9G( 0)| 0%| 62.9G| 15.7M| tmpfs | /sys/fs/cgroup |
/run | 0%| 0| 0| 0| 12.6G( 0)| 0%| 12.6G| 15.7M| tmpfs | /run |
/run/lock | 0%| 0| 0| 0| 5.0M( 0)| 0%| 5.0M| 15.7M| tmpfs | /run/lock |
/dev/shm | 0%| 0| 0| 0| 62.9G( 0)| 0%| 62.9G| 15.7M| tmpfs | /dev/shm |
==========================================================================================================================================================
>>>
# python3 guider/guider.py wtop -g yes
[Top Info] [Time: 7176629.490] [Interval: 1.0] [Ctxt: 195] [Life: +0/-0] [IRQ: 2688] [Core: 24] [Task: 327/434] [RAM: 63876] [Swap: 65491] (Unit: %/MB/NR)
[Cycle: 2G / Inst: 6G / IPC: 2.75 / CacheMiss: 202K(19%) / BranchMiss: 325K(0%) / Clock: 23G / MinFlt: 4 / MajFlt: 0]
==========================================================================================================================================================
ID | CPU (Usr/Ker/Blk/IRQ)| Mem (Diff/ User/Cache/Kern)| Swap (Diff/ I/O )|NrPgRclm | BlkRW | NrFlt | NrBlk | NrSIRQ | NrMlk | NrDrt | Network |
----------------------------------------------------------------------------------------------------------------------------------------------------------
Total | 5 %( 4 / 0 / 0 / 0 )| 4719( 0/ 856/57152/1149)| 0 ( 0 / 0/0 )| 0/0 | 0/0 | 0 | 0 | 2410 | 0 | 2 | 1K/5K |
==========================================================================================================================================================
Process ( PID/ PPID/ Nr/ Pri)| CPU(Usr/Ker/Dly)| Mem(RSS/Txt/Shr/Swp)| Blk( RD / WR /NrFlt)| Yld | Prmt | FD | LifeTime| WaitChannel |
----------------------------------------------------------------------------------------------------------------------------------------------------------
yes (22371/ 9085/ 1/R 90)| 99( 99/ 0/ 0)| 8( 0/ 0/ 0/ 0)| 0( -/ -/ 0)| 0| 0| 256| 0: 5:25| RUNNING |
(1)[STACK] | SIZE: 0M / RSS: 0M / PSS: 0M / SWAP: 0M / HUGE: 0M / LOCK: 0K / SDRT: 0K / PDRT: 8K / NOPM: 0K|
| WSS: [ 8K] -> 4K -> 4K -> 4K -> 4K -> 4K -> 4K -> 4K -> 4K -> 4K -> 4K -> 4K
(4)[FILE] | SIZE: 7M / RSS: 1M / PSS: 0M / SWAP: 0M / HUGE: 0M / LOCK: 0K / SDRT: 0K / PDRT: 40K / NOPM:2048K|
| WSS: [ 1M] -> 1M -> 1M -> 1M -> 1M -> 1M -> 1M -> 1M -> 1M -> 1M -> 1M -> 1M
(3)[ETC] | SIZE: 0M / RSS: 0M / PSS: 0M / SWAP: 0M / HUGE: 0M / LOCK: 0K / SDRT: 0K / PDRT: 0K / NOPM: 0K|
| WSS: [ 4K] -> 4K -> 4K -> 4K -> 4K -> 0 -> 0 -> 0 -> 0 -> 0 -> 4K -> 4K
(5)[ANON] | SIZE: 0M / RSS: 0M / PSS: 0M / SWAP: 0M / HUGE: 0M / LOCK: 0K / SDRT: 0K / PDRT: 48K / NOPM: 0K|
| WSS: [ 48K] -> 4K -> 4K -> 4K -> 4K -> 4K -> 4K -> 4K -> 4K -> 4K -> 4K -> 4K
----------------------------------------------------------------------------------------------------------------------------------------------------------
>>>
# python3 guider/guider.py btrace -g a.out -H
_start/0x55e321d151ee [/home/peacelee/test/a.out]
__libc_start_main/0x7ffb520af0b3 [/lib/x86_64-linux-gnu/libc-2.31.so]
main/0x55e321d15478 [/home/peacelee/test/a.out]
printPeace/0x55e321d15451 [/home/peacelee/test/a.out]
printPeace2/0x55e321d15392 [/home/peacelee/test/a.out]
asdfasdfasdfasdfasdfasdfasfdasdfasdfasdfasdfasdfasdfas/0x55e321d152e2 [/home/peacelee/test/a.out]
0.000384 read@GLIBC_2.26/0x7ffb52199130(-0x1,0x0,0x0,0x0,0x0,0x5) [/lib/x86_64-linux-gnu/libc-2.31.so]
0.000391 close@GLIBC_2.4/0x7ffb52199970(-0x1,0x0,0xffffffffffffff80,0x0,0x0,0x5) [/lib/x86_64-linux-gnu/libc-2.31.so]
0.000398 printf/0x7ffb520ece10(0x55e321d1600a,0x9,0xffffffffffffff80,0x0,0x0,0x5) [/lib/x86_64-linux-gnu/libc-2.31.so]
0.000405 __vfprintf_internal/0x7ffb521019e0(0x7ffb522746a0,0x55e321d1600a,0x7fff41688b40,0x55e321d1600a,0x0,0x5) [/lib/x86_64-linux-gnu/libc-2.31.so]
0.000412 __strchrnul_sse2/0x7ffb5213c820(0x55e321d1600a,0x25,0x7fff41688b40,0x55e321d1600a,0x0,0x5) [/lib/x86_64-linux-gnu/libc-2.31.so]
0.000420 _IO_new_file_xsputn/0x7ffb5211a750(0x7ffb522746a0,0x55e321d1600a,0x3,0x55e321d1600a,0x0,0x5) [/lib/x86_64-linux-gnu/libc-2.31.so]
0.000426 __mempcpy_sse2_unaligned_erms/0x7ffb52146d00(0x55e322290330,0x55e321d1600a,0x3,0x55e321d1600a,0x0,0x5) [/lib/x86_64-linux-gnu/libc-2.31.so]
0.000432 _itoa_word/0x7ffb520e6760(0x9,0x7fff41688af8,0xa,0x55e321d1600e,-0x1,0x3) [/lib/x86_64-linux-gnu/libc-2.31.so]
0.000439 _IO_new_file_xsputn/0x7ffb5211a750(0x7ffb522746a0,0x7fff41688af7,0x1,0x55e321d1600e,0x0,0x3) [/lib/x86_64-linux-gnu/libc-2.31.so]
0.000446 __mempcpy_sse2_unaligned_erms/0x7ffb52146d00(0x55e322290333,0x7fff41688af7,0x1,0x55e321d1600e,0x0,0x3) [/lib/x86_64-linux-gnu/libc-2.31.so]
0.000452 __strchrnul_sse2/0x7ffb5213c820(0x55e321d1600f,0x25,0x1,0x55e321d1600f,0x0,0x4) [/lib/x86_64-linux-gnu/libc-2.31.so]
0.000458 _IO_new_file_xsputn/0x7ffb5211a750(0x7ffb522746a0,0x55e321d1600f,0x1,0x55e321d1600f,0x0,0x4) [/lib/x86_64-linux-gnu/libc-2.31.so]
0.000464 __mempcpy_sse2_unaligned_erms/0x7ffb52146d00(0x55e322290334,0x55e321d1600f,0x1,0x55e321d1600f,0x0,0x4) [/lib/x86_64-linux-gnu/libc-2.31.so]
0.000471 _IO_file_overflow@GLIBC_2.2.5/0x7ffb5211bf00(0x7ffb522746a0,-0x1,0xc00,0x55e321d1600f,0x0,0x4) [/lib/x86_64-linux-gnu/libc-2.31.so]
0.000480 _IO_do_write@GLIBC_2.2.5/0x7ffb5211ba20(0x7ffb522746a0,0x55e322290330,0x5,0x55e321d1600f,0x0,0x4) [/lib/x86_64-linux-gnu/libc-2.31.so]
0.000486 _IO_file_write@GLIBC_2.2.5/0x7ffb52119fe0(0x7ffb522746a0,0x55e322290330,0x5,0x55e321d1600f,0x0,0x4) [/lib/x86_64-linux-gnu/libc-2.31.so]
0.000493 write@GLIBC_2.2.5/0x7ffb521991d0(0x1,0x55e322290330,0x5,0x55e321d1600f,0x0,0x4) [/lib/x86_64-linux-gnu/libc-2.31.so]
>>>
# python3 guider/guider.py btrace -g yes -H -c "*|getret"
0.532473 0x2cf0/0x560d7fd28cf0(0x1,0x560d81815440,0x2000,0x7faab23c8640,0x560d81815440,0x7c) [/usr/bin/yes]
0.532488 0x4c40/0x560d7fd2ac40(0x1,0x560d81815440,0x2000,0x7faab23c8640,0x560d81815440,0x7c) [/usr/bin/yes]
0.532501 write@GLIBC_2.2.5/0x7faab22f1040(0x1,0x560d81815440,0x2000,0x7faab23c8640,0x560d81815440,0x7c) [/lib/x86_64-linux-gnu/libc-2.31.so]
0.532516 write@GLIBC_2.2.5[RET]=0x2000(8192)/0.000015 -> 0x4c40/0x560d7fd26000 [/usr/bin/yes]
0.532557 0x4c40[RET]=0x2000(8192)/0.000069 -> 0x2cf0/0x560d7fd26000 [/usr/bin/yes]
0.532618 0x2cf0[RET]=0x2000(8192)/0.000145 -> 0x2580/0x560d7fd26000 [/usr/bin/yes]
0.532678 0x2cf0/0x560d7fd28cf0(0x1,0x560d81815440,0x2000,0x7faab23c8640,0x560d81815440,0x7c) [/usr/bin/yes]
0.532691 0x4c40/0x560d7fd2ac40(0x1,0x560d81815440,0x2000,0x7faab23c8640,0x560d81815440,0x7c) [/usr/bin/yes]
0.532706 write@GLIBC_2.2.5/0x7faab22f1040(0x1,0x560d81815440,0x2000,0x7faab23c8640,0x560d81815440,0x7c) [/lib/x86_64-linux-gnu/libc-2.31.so]
0.532721 write@GLIBC_2.2.5[RET]=0x2000(8192)/0.000015 -> 0x4c40/0x560d7fd26000 [/usr/bin/yes]
0.532798 0x4c40[RET]=0x2000(8192)/0.000107 -> 0x2cf0/0x560d7fd26000 [/usr/bin/yes]
0.532881 0x2cf0[RET]=0x2000(8192)/0.000204 -> 0x2580/0x560d7fd26000 [/usr/bin/yes]
0.532946 0x2cf0/0x560d7fd28cf0(0x1,0x560d81815440,0x2000,0x7faab23c8640,0x560d81815440,0x7c) [/usr/bin/yes]
0.532961 0x4c40/0x560d7fd2ac40(0x1,0x560d81815440,0x2000,0x7faab23c8640,0x560d81815440,0x7c) [/usr/bin/yes]
0.532975 write@GLIBC_2.2.5/0x7faab22f1040(0x1,0x560d81815440,0x2000,0x7faab23c8640,0x560d81815440,0x7c) [/lib/x86_64-linux-gnu/libc-2.31.so]
0.532990 write@GLIBC_2.2.5[RET]=0x2000(8192)/0.000015 -> 0x4c40/0x560d7fd26000 [/usr/bin/yes]
0.533067 0x4c40[RET]=0x2000(8192)/0.000106 -> 0x2cf0/0x560d7fd26000 [/usr/bin/yes]
0.533194 0x2cf0[RET]=0x2000(8192)/0.000248 -> 0x2580/0x560d7fd26000 [/usr/bin/yes]
>>>
$ python3 guider/guider.py rtop &
$ cat /tmp/guider.report
{
"task": {
"nrThread": 397,
"nrBlocked": 0,
"nrCtx": 4290,
"nrProc": 292
},
"mem": {
"kernel": 1432,
"anonDiff": -1,
"pgRclmFg": 0,
"cache": 35332,
"slabDiff": 0,
"free": 26929,
"anon": 698,
"pgDirty": 28,
"file": 31751,
"freeDiff": -1,
"pgRclmBg": 0,
"total": 64391,
"slab": 3581,
"fileDiff": -1
"procs": {
"1954": {
"text": 0,
"pid": 1954,
"rank": 2,
"comm": "ruby1.9.1",
"runtime": "110:43:32",
"rss": 104
},
},
"storage": {
"total": {
"read": 0,
"mount": {},
"favail": 133443655,
"free": 1141633,
"write": 1,
"usage": 1152423,
"total": 2294056,
"usageper": 50
},
"/dev/sdb1": {
"read": 0,
"mount": {
"path": "/mnt/hdd1",
"fs": "ext4",
"option": "rw,relatime,data=ordered"
},
"favail": 50709466,
"free": 293649,
"write": 0,
"usage": 645251,
"total": 938900,
"usageper": 68
},
},
"system": {
"load5m": 2.38,
"uptime": 4191643.92,
"nrSoftIrq": 7405,
"nrIrq": 7289,
"load15m": 0.84,
"interval": 1.029999999795109,
"pid": 14578,
"load1m": 9.39
},
"event": {
"CPU_INTENSIVE": {
"14592": {
"kernel": 0,
"runtime": "0:0:47",
"pid": 14592,
"rank": 3,
"comm": "yes",
"user": 99,
"total": 100
},
"14593": {
"kernel": 0,
"runtime": "0:0:46",
"pid": 14593,
"rank": 10,
"comm": "yes",
"user": 99,
"total": 100
},
},
"swap": {
"usage": 76,
"total": 65491,
"usageDiff": 0
},
"net": {
"inbound": 1479,
"outbound": 392
},
"cpu": {
"kernel": 0,
"iowait": 0,
"nrCore": 24,
"idle": 8,
"user": 91,
"irq": 0,
"total": 92,
"procs": {
"14592": {
"kernel": 0,
"runtime": "0:0:47",
"pid": 14592,
"rank": 3,
"comm": "yes",
"user": 99,
"total": 100
},
},
"block": {
"read": 0,
"write": 0,
"procs": {},
"nrMajFlt": 0,
"ioWait": 0
}
}
>>>
# python3 guider/guider.py limitcpu -g yes:50 -v
[Info] limited cpu usage of yes(22371) process to 50%, it used 50%
[WARN] started 1th guider(574420)
[WARN] 1th guider(574420) took 0.421747 seconds to finish one job
>>>
# python3 guider/guider.py sigtrace -g a.out
[INFO] start profiling a.out(3100585)...
0.000130 [SIGUSR1] {si_code=SI_USER si_pid=a.out(3100585), si_uid=root(0)}
0.000276 [SIGUSR2] {si_code=SI_USER si_pid=a.out(3100585), si_uid=root(0)}
0.000287 [SIGRT1] {si_code=SI_USER si_pid=a.out(3100585), si_uid=root(0)}
0.000307 [SIGUSR1] {si_code=SI_USER si_pid=a.out(3100585), si_uid=root(0)}
0.000317 [SIGUSR2] {si_code=SI_USER si_pid=a.out(3100585), si_uid=root(0)}
0.000326 [SIGRT2] {si_code=SI_USER si_pid=a.out(3100585), si_uid=root(0)}
1.955804 [SIGCHLD] {si_code=CLD_EXITED si_pid=3100586, si_uid=0, si_status=0 si_utime=0, si_stime=0}
1.955816 [SIGUSR1] {si_code=SI_USER si_pid=a.out(3100585), si_uid=root(0)}
1.955826 [SIGUSR2] {si_code=SI_USER si_pid=a.out(3100585), si_uid=root(0)}
1.955836 [SIGRT3] {si_code=SI_USER si_pid=a.out(3100585), si_uid=root(0)}
1.955846 [SIGUSR1] {si_code=SI_USER si_pid=a.out(3100585), si_uid=root(0)}
1.955856 [SIGUSR2] {si_code=SI_USER si_pid=a.out(3100585), si_uid=root(0)}
1.955866 [SIGRT4] {si_code=SI_USER si_pid=a.out(3100585), si_uid=root(0)}
1.955875 [SIGUSR1] {si_code=SI_USER si_pid=a.out(3100585), si_uid=root(0)}
1.955884 [SIGUSR2] {si_code=SI_USER si_pid=a.out(3100585), si_uid=root(0)}
1.955893 [SIGRT5] {si_code=SI_USER si_pid=a.out(3100585), si_uid=root(0)}
1.955903 [SIGUSR1] {si_code=SI_USER si_pid=a.out(3100585), si_uid=root(0)}
1.955912 [SIGUSR2] {si_code=SI_USER si_pid=a.out(3100585), si_uid=root(0)}
1.955922 [SIGRT6] {si_code=SI_USER si_pid=a.out(3100585), si_uid=root(0)}
1.955931 [SIGUSR1] {si_code=SI_USER si_pid=a.out(3100585), si_uid=root(0)}
1.955941 [SIGUSR2] {si_code=SI_USER si_pid=a.out(3100585), si_uid=root(0)}
1.955950 [SIGRT7] {si_code=SI_USER si_pid=a.out(3100585), si_uid=root(0)}
1.955959 [SIGUSR1] {si_code=SI_USER si_pid=a.out(3100585), si_uid=root(0)}
1.955969 [SIGUSR2] {si_code=SI_USER si_pid=a.out(3100585), si_uid=root(0)}
1.955978 [SIGRT8] {si_code=SI_USER si_pid=a.out(3100585), si_uid=root(0)}
1.955987 [SIGUSR1] {si_code=SI_USER si_pid=a.out(3100585), si_uid=root(0)}
1.955997 [SIGUSR2] {si_code=SI_USER si_pid=a.out(3100585), si_uid=root(0)}
1.956006 [SIGRT9] {si_code=SI_USER si_pid=a.out(3100585), si_uid=root(0)}
1.956015 [SIGUSR1] {si_code=SI_USER si_pid=a.out(3100585), si_uid=root(0)}
1.956025 [SIGSEGV] {si_code=SEGV_MAPERR si_addr=0x4d2}
2.191489 +++ exited a.out(3100585) with 139 +++
>>>
# python3 guider/guider.py setsched r:90:yes
[Info] changed the priority of yes(22371) to 90[R]
>>>
# python3 guider/guider.py remote -g a.out -c usercall:write#1#HOOK#4
[usercall] write(7f94ed747140)(1, HOOK, 4) = 0x4(4)
>>>
# python3 guider/guider.py printenv -g systemd
[ systemd(1) ]
-----------------------------------------------------------------------------
HOME=/
init=/sbin/init
NETWORK_SKIP_ENSLAVED=
recovery=
TERM=linux
drop_caps=
BOOT_IMAGE=/boot/vmlinuz-5.3.0-28-generic
PATH=/sbin:/usr/sbin:/bin:/usr/bin
PWD=/
rootmnt=/root
[ systemd(3310) ]
-----------------------------------------------------------------------------
LANG=en_US.UTF-8
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
NOTIFY_SOCKET=/run/systemd/notify
HOME=/home/syjung
LOGNAME=syjung
USER=syjung
SHELL=/bin/bash
INVOCATION_ID=bbc56cc8552e4a1d815197e0a6160270
JOURNAL_STREAM=9:10617556
XDG_RUNTIME_DIR=/run/user/1002
[ systemd(7094) ]
-----------------------------------------------------------------------------
LANG=en_US.UTF-8
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
NOTIFY_SOCKET=/run/systemd/notify
HOME=/home/peacelee
LOGNAME=peacelee
USER=peacelee
SHELL=/bin/bash
INVOCATION_ID=be65ebdd72964e09a3ac06495261702b
JOURNAL_STREAM=9:31410
XDG_RUNTIME_DIR=/run/user/1004
>>>
# python3 guider/guider.py kill -stop yes
[Info] sent SIGSTOP to yes(10594)
>>>
# python3 guider/guider.py printbind -g yes
[Function Bind Info] [Target: yes(410113)]
==========================================================================================================================================================
Path Type Sym[Bind/Vis] => Link
----------------------------------------------------------------------------------------------------------------------------------------------------------
[/usr/bin/yes]
NOTYPE _ITM_deregisterTMCloneTable@GLIBC_2.2.5[WEAK/DEFAULT] => NONE
NOTYPE _ITM_registerTMCloneTable@GLIBC_2.2.5[WEAK/DEFAULT] => NONE
FUNC __ctype_b_loc@GLIBC_2.2.5[GLOBAL/DEFAULT] => __ctype_b_loc/0x7f474b600400[/usr/lib/x86_64-linux-gnu/libc-2.31.so/0x37400]
FUNC __cxa_atexit@GLIBC_2.2.5[GLOBAL/DEFAULT] => __cxa_atexit@GLIBC_2.2.5/0x7f474b612f60[/usr/lib/x86_64-linux-gnu/libc-2.31.so/0x49f60]
FUNC __cxa_finalize@GLIBC_2.2.5[WEAK/DEFAULT] => __cxa_finalize@GLIBC_2.2.5/0x7f474b613090[/usr/lib/x86_64-linux-gnu/libc-2.31.so/0x4a090]
FUNC __fpending@GLIBC_2.2.5[GLOBAL/DEFAULT] => __fpending@GLIBC_2.2.5/0x7f474b658f80[/usr/lib/x86_64-linux-gnu/libc-2.31.so/0x8ff80]
FUNC __fprintf_chk[GLOBAL/DEFAULT] => __fprintf_chk@GLIBC_2.14/0x7f474b6fa110[/usr/lib/x86_64-linux-gnu/libc-2.31.so/0x131110]
FUNC __freading@GLIBC_2.2.5[GLOBAL/DEFAULT] => __freading@GLIBC_2.2.5/0x7f474b658e90[/usr/lib/x86_64-linux-gnu/libc-2.31.so/0x8fe90]
NOTYPE __gmon_start__@GLIBC_2.14[WEAK/DEFAULT] => NONE
FUNC __libc_start_main@GLIBC_2.2.5[GLOBAL/DEFAULT] => __libc_start_main@GLIBC_2.2.5/0x7f474b5effc0[/usr/lib/x86_64-linux-gnu/libc-2.31.so/0x26fc0]
FUNC __printf_chk@GLIBC_2.2.5[GLOBAL/DEFAULT] => __printf_chk@GLIBC_2.2.5/0x7f474b6fa040[/usr/lib/x86_64-linux-gnu/libc-2.31.so/0x131040]
FUNC __stack_chk_fail@GLIBC_2.2.5[GLOBAL/DEFAULT] => __stack_chk_fail@GLIBC_2.2.5/0x7f474b6fbb00[/usr/lib/x86_64-linux-gnu/libc-2.31.so/0x132b00]
FUNC _exit@GLIBC_2.2.5[GLOBAL/DEFAULT] => _Exit@GLIBC_2.3/0x7f474b6af290[/usr/lib/x86_64-linux-gnu/libc-2.31.so/0xe6290]
FUNC abort@GLIBC_2.2.5[GLOBAL/DEFAULT] => abort@GLIBC_2.2.5/0x7f474b5ee72e[/usr/lib/x86_64-linux-gnu/libc-2.31.so/0x2572e]
FUNC bindtextdomain@GLIBC_2.2.5[GLOBAL/DEFAULT] => bindtextdomain@GLIBC_2.2.5/0x7f474b600920[/usr/lib/x86_64-linux-gnu/libc-2.31.so/0x37920]
FUNC calloc[GLOBAL/DEFAULT] => calloc@GLIBC_2.2.5/0x7f474b667c90[/usr/lib/x86_64-linux-gnu/libc-2.31.so/0x9ec90]
----------------------------------------------------------------------------------------------------------------------------------------------------------
>>>
# python3 guider/guider.py rec -a -e m,b
[Thread Info] [ Elapsed: 2.050 ] [ Start: 2849868.198 ] [ Running: 112 ] [ CtxSwc: 3357 ] [ LogSize: 4054 KB ] [ Unit: Sec/MB/NR ]
==========================================================================================================================================================
__________Thread Info___________|_____________CPU Info______________|______SCHED Info______|________BLOCK Info________|_____________MEM Info_____________|
| | | | |
Name( Tid/ Pid)|LF|Usage( %)|Delay( Max)|Pri| IRQ | Yld| Lose|Steal| Mig| Read( MB/ Cnt)|WCnt( MB)| Sum(Usr/Buf/Ker)|Rcl|Wst|DRcl(Nr)|
==========================================================================================================================================================
# CPU: 12
CORE/0(-----/-----)|--| 0.00( 0.1)| 0.00( 0.00)| 0| 0.00| 7| -| -| -| 0.00( 0/ 1)| 0( 0)| 0( 0/ 0/ 0)| 0| 0|0.00( 0)|
CORE/1(-----/-----)|--| 0.00( 0.1)| 0.10( 0.00)| 0| 0.00| 147| -| -| -| 0.00( 0/ 0)| 0( 0)| 0( 0/ 0/ 0)| 0| 0|0.00( 0)|
CORE/2(-----/-----)|--| 0.00( 0.1)| 0.16( 0.00)| 0| 0.00| 211| -| -| -| 0.00( 0/ 0)| 0( 0)| 0( 0/ 0/ 0)| 0| 0|0.00( 0)|
CORE/3(-----/-----)|--| 0.00( 0.1)| 0.11( 0.00)| 0| 0.00| 181| -| -| -| 0.00( 0/ 0)| 32( 0)| 0( 0/ 0/ 0)| 0| 0|0.00( 0)|
CORE/4(-----/-----)|--| 0.00( 0.1)| 0.11( 0.00)| 0| 0.00| 232| -| -| -| 0.00( 0/ 0)| 0( 0)| 0( 0/ 0/ 0)| 0| 0|0.00( 0)|
CORE/5(-----/-----)|--| 0.30( 14.8)| 0.18( 0.00)| 0| 0.00| 179| -| -| -| 1.26( 6/ 495)| 19( 0)| 61( 57/ 0/ 3)| 0| 0|0.00( 0)|
CORE/6(-----/-----)|--| 0.00( 0.0)| 0.35( 0.00)| 0| 0.00| 57| -| -| -| 0.00( 0/ 0)| 0( 0)| 0( 0/ 0/ 0)| 0| 0|0.00( 0)|
CORE/7(-----/-----)|--| 0.00( 0.0)| 0.60( 0.00)| 0| 0.00| 100| -| -| -| 0.00( 0/ 0)| 0( 0)| 0( 0/ 0/ 0)| 0| 0|0.00( 0)|
CORE/8(-----/-----)|--| 0.00( 0.0)| 0.44( 0.00)| 0| 0.00| 59| -| -| -| 0.00( 0/ 0)| 0( 0)| 0( 0/ 0/ 0)| 0| 0|0.00( 0)|
CORE/9(-----/-----)|--| 0.00( 0.0)| 1.94( 0.00)| 0| 0.00| 37| -| -| -| 0.00( 0/ 0)| 0( 0)| 0( 0/ 0/ 0)| 0| 0|0.00( 0)|
CORE/10(-----/-----)|--| 0.07( 3.4)| 0.00( 0.00)| 0| 0.00| 2| -| -| -| 0.00( 0/ 0)| 0( 0)| 0( 0/ 0/ 0)| 0| 0|0.00( 0)|
CORE/11(-----/-----)|--| 0.00( 0.0)| 2.05( 0.00)| 0| 0.00| 39| -| -| -| 0.00( 0/ 0)| 0( 0)| 0( 0/ 0/ 0)| 0| 0|0.00( 0)|
----------------------------------------------------------------------------------------------------------------------------------------------------------
# Hot: 4
synergyc( 3604/ 3602)| | 0.17( 8.5)| 0.00( 0.00)| 0| 0.00| 3| 14| 3| 0| 0.00( 0/ 0)| 0( 0)| 0( 0/ 0/ 0)| 0| 0|0.00( 0)|
arm-starfish-li(16087/16087)| | 0.13( 6.3)| 0.00( 0.00)| 0| 0.00| 0| 20| 157| 4| 1.26( 6/ 496)| 0( 0)| 61( 57/ 0/ 3)| 0| 0|0.00( 0)|
guider(16088/16088)| | 0.07( 3.4)| 0.00( 0.00)|R90| 0.00| 2| 0| 2| 0| 0.00( 0/ 0)| 0( 0)| 0( 0/ 0/ 0)| 0| 0|0.00( 0)|
----------------------------------------------------------------------------------------------------------------------------------------------------------
>>>
# python3 guider/guider.py iorec -s
# python3 guider/guider.py report -a
[Thread Block Info] (Unit: NR)
==========================================================================================================================================================
ID OPT NrDev TOTAL SEQUENTIAL( %) FS PATH
[ACCESS] COUNT
==========================================================================================================================================================
TOTAL READ 8:3 131.8M 131.3M( 99.6) - /dev/sda3
[ 4.0K - 7.0K] 370
[ 16.0K - 31.0K] 11
[ 32.0K - 63.0K] 6
[ 64.0K - 127.0K] 5
[ 128.0K - 255.0K] 1037
253:0 131.8M 131.3M( 99.6) ext4 /
[ 4.0K - 7.0K] 370
[ 16.0K - 31.0K] 11
[ 32.0K - 63.0K] 6
[ 64.0K - 127.0K] 5
[ 128.0K - 255.0K] 1037
WRITE 253:0 40.0K 20.0K( 50.0) ext4 /
[ 4.0K - 7.0K] 10
8:3 24.0K 20.0K( 83.3) - /dev/sda3
[ 4.0K - 7.0K] 6
----------------------------------------------------------------------------------------------------------------------------------------------------------
guider(4011197) READ 8:3 100.0M 100.0M(100.0) - /dev/sda3
[ 16.0K - 31.0K] 2
[ 32.0K - 63.0K] 1
[ 64.0K - 127.0K] 1
[ 128.0K - 255.0K] 799
253:0 100.0M 100.0M(100.0) ext4 /
[ 16.0K - 31.0K] 2
[ 32.0K - 63.0K] 1
[ 64.0K - 127.0K] 1
[ 128.0K - 255.0K] 799
----------------------------------------------------------------------------------------------------------------------------------------------------------
[Thread FS Info] (Unit: NR)
==========================================================================================================================================================
ID OPT NrDev INODE Size FS PATH
==========================================================================================================================================================
TOTAL WRITE 16.0K
253:0 16.0K ext4 /
0 16.0K
READ 131.8M
0:3 1.4M ? ?
0 1.4M
253:0 130.4M ext4 /
24520383 100.0M /home/peacelee/guider/guider/TEST2[100.0M]
24520372 20.0M /home/peacelee/guider/guider/TEST[20.0M]
24520353 10.0M /home/peacelee/guider/guider/TEST3[10.0M]
6030383 84.0K
6819964 72.0K
6029790 68.0K
6031485 44.0K
6031543 40.0K
6819797 16.0K
6035523 16.0K
0 16.0K
6818557 4.0K
6818689 4.0K
7078584 4.0K
----------------------------------------------------------------------------------------------------------------------------------------------------------
guider(4011197) READ 100.0M
253:0 100.0M ext4 /
24520383 100.0M /home/peacelee/guider/guider/TEST2[100.0M]
----------------------------------------------------------------------------------------------------------------------------------------------------------
guider(4011193) READ 20.0M
253:0 20.0M ext4 /
24520372 20.0M /home/peacelee/guider/guider/TEST[20.0M]
----------------------------------------------------------------------------------------------------------------------------------------------------------
>>>
# python3 guider/guider.py iorec -s
# python3 guider/guider.py report -q RALIST
# python3 guider/guider.py readahead readahead.list
[INFO] start readahead from '/home/peacelee/guider/guider/readahead.list'
[INFO] changed the CPU scheduling priority for guider(4011281) to 10[C]
[INFO] changed the I/O scheduling priority for guider(4011281) to IOPRIO_CLASS_IDLE(0)[IOPRIO_WHO_PROCESS]
[INFO] finished readahead a total of 130.0M data for 0.002 sec
>>>
# python3 guider/guider.py sysrec
[Thread Syscall Info] (Unit: Sec/NR)
==========================================================================================================================================================
Name( Tid) Syscall( ID) Elapsed Count Error Min Max Avg
==========================================================================================================================================================
arm-linux-gnuea( 3000)
close( 3) 0.039396 69 0 0.000001 0.005353 0.000571
stat( 4) 0.011521 74 0 0.000001 0.009423 0.000156
fchmod( 91) 0.000046 3 0 0.000002 0.000039 0.000015
getpriority(140) 0.000017 33 0 0.000000 0.000001 0.000001
lgetxattr(192) 0.000014 3 0 0.000003 0.000008 0.000005
recvfrom( 45) 0.000004 1 0 0.000004 0.000004 0.000004
----------------------------------------------------------------------------------------------------------------------------------------------------------
guider( 3001)
pause( 34) 0.283474 1 1 0.283474 0.283474 0.283474
select( 23) 0.100122 1 0 0.100122 0.100122 0.100122
write( 1) 0.000234 6 0 0.000031 0.000059 0.000039
open( 2) 0.000084 7 0 0.000007 0.000038 0.000012
ioctl( 16) 0.000009 14 14 0.000001 0.000001 0.000001
fstat( 5) 0.000006 14 0 0.000001 0.000001 0.000000
lseek( 8) 0.000006 21 0 0.000000 0.000001 0.000000
close( 3) 0.000005 7 0 0.000000 0.000001 0.000001
rt_sigaction( 13) 0.000001 1 0 0.000001 0.000001 0.000001
----------------------------------------------------------------------------------------------------------------------------------------------------------
mysqld( 3237)
futex(202) 0.000000 1 0 0.000000 0.000000 0.000000
----------------------------------------------------------------------------------------------------------------------------------------------------------
mysqld( 3238)
futex(202) 0.000002 1 0 0.000002 0.000002 0.000002
----------------------------------------------------------------------------------------------------------------------------------------------------------
screen( 9045)
select( 23) 0.000082 4 0 0.000004 0.000069 0.000021
----------------------------------------------------------------------------------------------------------------------------------------------------------
>>>
# python3 guider/guider.py rec -e L
[Thread Futex Lock Info] [ Elapsed : 1.225 ] (Unit: Sec/NR)
==========================================================================================================================================================
Name( Tid/ Pid) Elapsed Process Block NrBlock CallMax Lock LockMax NrLock NrWait LBlock NrLBlock LastStat
==========================================================================================================================================================
mysqld( 3236/ 3208) 0.469 0.000 0.469 1 0.469 0.000 0.000 0 1 0.000 0 Wait
----------------------------------------------------------------------------------------------------------------------------------------------------------
mysqld( 3237/ 3208) 0.890 0.000 0.890 1 0.890 0.000 0.000 0 1 0.000 0 Wait
----------------------------------------------------------------------------------------------------------------------------------------------------------
mysqld( 3238/ 3208) 1.075 0.000 1.075 1 1.075 0.000 0.000 0 1 0.000 0 Wait
----------------------------------------------------------------------------------------------------------------------------------------------------------
[Thread File Lock Info] (Unit: Sec/NR)
==========================================================================================================================================================
Name( Tid) Wait Lock nrTryLock nrLocked
==========================================================================================================================================================
smbd( 2631) 0.000 0.000 3 3
----------------------------------------------------------------------------------------------------------------------------------------------------------
>>>
# python3 guider/guider.py rec -s . -K openfile:getname::**string
[Thread KERNEL Event Info]
==========================================================================================================================================================
Event Comm( Tid ) Usage Count ProcMax ProcMin InterMax InterMin
==========================================================================================================================================================
openfile TOTAL( - ) 0.000729 1012 0.000013 0.000001 1.979834 0.000109
ps(10728) 0.000640 968 0.000013 0.000000 0.001636 0.000006
python2(10727) 0.000038 26 0.000004 0.000001 1.979834 0.000020
tmux( 6959) 0.000031 9 0.000006 0.000003 0.299492 0.201316
PassengerAgent(23183) 0.000008 5 0.000002 0.000001 0.007375 0.000109
sendmail-mta( 3419) 0.000007 2 0.000006 0.000001 0.000077 0.000077
PassengerAgent(10729) 0.000003 1 0.000003 0.000003 0.000000 0.000000
smbd(11086) 0.000002 1 0.000002 0.000002 0.000000 0.000000
----------------------------------------------------------------------------------------------------------------------------------------------------------
[Thread KERNEL Event History]
==========================================================================================================================================================
EVENT TYPE TIME COMM( TID) CALLER ELAPSED ARG
==========================================================================================================================================================
openfile EXIT 0.063942 tmux( 6959) porch_do_sys_open 0.000003 1>"/proc/7969/cmdline"
openfile ENTER 0.137626 python2(10727) -
openfile EXIT 0.137628 python2(10727) porch_do_sys_open 0.000002 1>"/sys/kernel/debug/tracing/trace"
openfile ENTER 0.363431 tmux( 6959) -
openfile EXIT 0.363437 tmux( 6959) porch_do_sys_open 0.000006 1>"/proc/7197/cmdline"
openfile ENTER 0.510452 smbd(11086) -
openfile EXIT 0.510454 smbd(11086) porch_do_sys_open 0.000002 1>"/var/log/samba/log.jhkim-z97x-ud3h"
openfile ENTER 0.564845 tmux( 6959) -
openfile EXIT 0.564848 tmux( 6959) porch_do_sys_open 0.000003 1>"/proc/7969/cmdline"
openfile ENTER 0.864255 tmux( 6959) -
openfile EXIT 0.864258 tmux( 6959) porch_do_sys_open 0.000003 1>"/proc/7197/cmdline"
openfile ENTER 1.065571 tmux( 6959) -
openfile EXIT 1.065574 tmux( 6959) porch_do_sys_open 0.000003 1>"/proc/7969/cmdline"
openfile ENTER 1.364980 tmux( 6959) -
openfile EXIT 1.364984 tmux( 6959) porch_do_sys_open 0.000004 1>"/proc/7197/cmdline"
openfile ENTER 1.437128 sendmail-mta( 3419) -
openfile EXIT 1.437134 sendmail-mta( 3419) porch_do_sys_open 0.000006 1>"/proc/loadavg"
openfile ENTER 1.437205 sendmail-mta( 3419) -
openfile EXIT 1.437206 sendmail-mta( 3419) porch_do_sys_open 0.000001 1>"/proc/loadavg"
openfile ENTER 1.566369 tmux( 6959) -
openfile EXIT 1.566372 tmux( 6959) porch_do_sys_open 0.000003 1>"/proc/7969/cmdline"
openfile ENTER 1.865776 tmux( 6959) -
openfile EXIT 1.865779 tmux( 6959) porch_do_sys_open 0.000003 1>"/proc/7197/cmdline"
openfile ENTER 1.955265 PassengerAgent(10729) -
openfile EXIT 1.955268 PassengerAgent(10729) porch_do_sys_open 0.000003 1>"/dev/fd"
----------------------------------------------------------------------------------------------------------------------------------------------------------
>>>
# python3 guider/guider.py funcrec -s .
# python3 guider/guider.py report -a
# cat guider.out
[Function CPU Info] [Cnt: 394] [Interval: 8ms] (USER)
==========================================================================================================================================================
__Usage__|___________________Function____________________|_____________________________________________Binary_____________________________________________
==========================================================================================================================================================
99.0% | cpuTest | /media/disk/work/test/a.out
+ 100.0% | <- startTest [/media/disk/work/test/a.out] <- main [/media/disk/work/test/a.out]
<- __libc_start_main [/lib/x86_64-linux-gnu/libc-2.19.so]
----------------------------------------------------------------------------------------------------------------------------------------------------------
0.5% | memset | /lib/x86_64-linux-gnu/libc-2.19.so
+ 100.0% | <- startTest [/media/disk/work/test/a.out] <- main [/media/disk/work/test/a.out]
<- __libc_start_main [/lib/x86_64-linux-gnu/libc-2.19.so]
----------------------------------------------------------------------------------------------------------------------------------------------------------
0.3% | _int_malloc | /lib/x86_64-linux-gnu/libc-2.19.so
----------------------------------------------------------------------------------------------------------------------------------------------------------
0.3% | 00007f756e3e7ee4 | ??
+ 100.0% | <- 000000000044676f [/media/disk/work/test/a.out]
----------------------------------------------------------------------------------------------------------------------------------------------------------
[Function CPU Info] [Cnt: 394] [Interval: 8ms] (KERNEL)
==========================================================================================================================================================
__Usage__|____________________________________________________________________Function____________________________________________________________________
==========================================================================================================================================================
100.0% | hrtimer_interrupt
+ 99.5% | <- local_apic_timer_interrupt <- smp_apic_timer_interrupt <- apic_timer_interrupt
+ 0.3% | <- local_apic_timer_interrupt <- smp_apic_timer_interrupt <- apic_timer_interrupt <- do_page_fault <- page_fault
+ 0.3% | <- local_apic_timer_interrupt <- smp_apic_timer_interrupt <- apic_timer_interrupt <- __do_fault <- handle_mm_fault <- __do_page_fault
<- do_page_fault <- page_fault
----------------------------------------------------------------------------------------------------------------------------------------------------------
>>>
# python3 guider/guider.py funcrec -e m -s .
# python3 guider/guider.py report -a
# cat guider.out
[Function Page Info] [Total: 11.4M] [Alloc: 11.4M(817)] [Free: 188.0K(47)] (USER)
==========================================================================================================================================================
Usage ( Usr / Buf / Ker )|___________________Function____________________|________________LifeTime________________|______________Binary_______________
==========================================================================================================================================================
10256K( 2048/ 0/ 8208)| memset | AVR: 1.563 / MIN: 1.560 / MAX: 1.568 | /lib/x86_64-linux-gnu/libc-2.19.so
+ 10256K( 2048/ 0/ 8208)| <- startTest [/media/disk/work/test/a.out] <- main [/media/disk/work/test/a.out]
<- __libc_start_main [/lib/x86_64-linux-gnu/libc-2.19.so]
----------------------------------------------------------------------------------------------------------------------------------------------------------
960K( 956/ 0/ 4)| _int_malloc | AVR: 1.559 / MIN: 1.554 / MAX: 1.560 | /lib/x86_64-linux-gnu/libc-2.19.so
----------------------------------------------------------------------------------------------------------------------------------------------------------
56K( 16/ 0/ 40)| 00007f756e3e81e7 | AVR: 1.569 / MIN: 1.568 / MAX: 1.569 | ??
----------------------------------------------------------------------------------------------------------------------------------------------------------
44K( 36/ 0/ 8)| sysmalloc | AVR: 1.560 / MIN: 1.558 / MAX: 1.568 | /lib/x86_64-linux-gnu/libc-2.19.so
----------------------------------------------------------------------------------------------------------------------------------------------------------
12K( 12/ 0/ 0)| elf_machine_rela_relative | AVR: 1.568 / MIN: 1.568 / MAX: 1.568 | /lib/x86_64-linux-gnu/ld-2.19.so
+ 12K( 12/ 0/ 0)| <- dl_main [/lib/x86_64-linux-gnu/ld-2.19.so] <- _dl_sysdep_start [/lib/x86_64-linux-gnu/ld-2.19.so]
----------------------------------------------------------------------------------------------------------------------------------------------------------
8K( 8/ 0/ 0)| realloc | AVR: 1.568 / MIN: 1.568 / MAX: 1.568 | /lib/x86_64-linux-gnu/ld-2.19.so
+ 4K( 4/ 0/ 0)| <- _dl_map_object [/lib/x86_64-linux-gnu/ld-2.19.so]
----------------------------------------------------------------------------------------------------------------------------------------------------------
8K( 4/ 0/ 4)| dl_main | AVR: 1.568 / MIN: 1.568 / MAX: 1.568 | /lib/x86_64-linux-gnu/ld-2.19.so
+ 8K( 4/ 0/ 4)| <- _dl_sysdep_start [/lib/x86_64-linux-gnu/ld-2.19.so]
----------------------------------------------------------------------------------------------------------------------------------------------------------
[Function Page Info] [Total: 11.4K] [Alloc: 11.4K(817)] [Free: 188.0K(47)] (KERNEL)
==========================================================================================================================================================
Usage ( Usr / Buf / Ker )|___________________Function____________________|__________________________________LifeTime__________________________________
==========================================================================================================================================================
8192K( 0/ 0/ 8192)| do_huge_pmd_anonymous_page | AVR: 1.563 / MIN: 1.562 / MAX: 1.564
+ 8192K( 0/ 0/ 8192)| <- handle_mm_fault <- __do_page_fault <- do_page_fault <- page_fault
----------------------------------------------------------------------------------------------------------------------------------------------------------
3084K( 3084/ 0/ 0)| handle_mm_fault | AVR: 1.563 / MIN: 1.554 / MAX: 1.569
+ 3076K( 3076/ 0/ 0)| <- __do_page_fault <- do_page_fault <- page_fault
+ 4K( 4/ 0/ 0)| <- __get_user_pages <- get_user_pages <- copy_strings.isra.17 <- copy_strings_kernel <- do_execve_common.isra.23
<- SyS_execve <- stub_execve
+ 4K( 4/ 0/ 0)| <- __do_page_fault <- do_page_fault <- page_fault <- load_elf_binary <- search_binary_handler
<- do_execve_common.isra.23 <- SyS_execve <- stub_execve
----------------------------------------------------------------------------------------------------------------------------------------------------------
>>>
# python3 guider/guider.py filerec
[File Usage Info] [ File: 281 ] [ RAM: 78.0M ] [ Keys: Foward/Back/Save/Quit ]
==========================================================================================================================================================
____RAM_____|___File___|__%___|_____________________________________________________Library & Process_____________________________________________________
==========================================================================================================================================================
7,616 | 7,616 | 100 | /run/samba/locking.tdb [Proc: 10] [Link: 1]
| smbd ( 2937) | smbd ( 9178) | smbd (21387) | smbd ( 3356) |
| smbd ( 2828) | smbd ( 2417) | smbd ( 3862) | smbd ( 2631) |
| smbd (11086) | smbd ( 729) |
----------------------------------------------------------------------------------------------------------------------------------------------------------
6,076 | 8,452 | 71 | /usr/lib/apache2/modules/libphp5.so [Proc: 11] [Link: 1]
| /usr/sbin/apach (13071) | /usr/sbin/apach (13073) | /usr/sbin/apach ( 3817) | /usr/sbin/apach ( 9111) |
| /usr/sbin/apach (20085) | /usr/sbin/apach ( 7221) | /usr/sbin/apach ( 345) | /usr/sbin/apach ( 346) |
| /usr/sbin/apach ( 7222) | /usr/sbin/apach (14278) | /usr/sbin/apach ( 9715) |
----------------------------------------------------------------------------------------------------------------------------------------------------------
5,784 | 9,828 | 58 | /usr/sbin/smbd [Proc: 10] [Link: 1]
| smbd ( 2937) | smbd ( 9178) | smbd (21387) | smbd ( 3356) |
| smbd ( 2828) | smbd ( 2417) | smbd ( 3862) | smbd ( 2631) |
| smbd (11086) | smbd ( 729) |
----------------------------------------------------------------------------------------------------------------------------------------------------------
4,800 | 25,880 | 18 | /var/lib/gems/1.9.1/gems/passenger-5.1.0/buildout/support-binaries/PassengerAgent [Proc: 3] [Link: 1]
| PassengerAgent (23161) | PassengerAgent (23176) | PassengerAgent (23191) |
----------------------------------------------------------------------------------------------------------------------------------------------------------
3,612 | 12,016 | 30 | /usr/sbin/mysqld [Proc: 1] [Link: 1]
| mysqld ( 3208) |
----------------------------------------------------------------------------------------------------------------------------------------------------------
2,988 | 2,988 | 100 | /usr/lib/libpython2.7.so.1.0 [Proc: 6] [Link: 1]
| vi (18865) | vi (28546) | vi ( 7200) | vi (22546) |
| vi ( 8826) | vi ( 8135) |
----------------------------------------------------------------------------------------------------------------------------------------------------------
2,228 | 2,884 | 77 | /usr/bin/python3.2mu [Proc: 1] [Link: 1]
| guider (22637) |
----------------------------------------------------------------------------------------------------------------------------------------------------------
2,016 | 2,016 | 100 | /usr/lib/libruby-1.9.1.so.1.9.1 [Proc: 1] [Link: 1]
| ruby1.9.1 (23294) |
----------------------------------------------------------------------------------------------------------------------------------------------------------
>>>
$ python3 guider/guider.py top -o guider.out
$ python3 guider/guider.py draw guider.out
>>>
>>>
# python3 guider/guider.py rec -s guider.dat
# python3 guider/guider.py draw guider.dat
>>>
>>>
# python3 guider/guider.py utop -g testTask -H -o guider.out
# python3 guider/guider.py drawflame guider.out
>>>
>>>
$ python3 guider/guider.py top -o test1.out
$ python3 guider/guider.py top -o test2.out
$ python3 guider/guider.py top -o test3.out
$ python3 guider/guider.py top -o test4.out
$ python3 guider/guider.py top -o test5.out
$ python3 guider/guider.py drawavg "test1.out, test2.out, test3.out, test4.out, test5.out"
>>>
>>>
$ python3 guider/guider.py req "https://www.google.com|https://www.naver.com" -R 1000 -o guider.out
$ python3 guider/guider.py drawreq guider.out
>>>
>>>
webservice
>>>
How to use
=======
```
To view a list of all commands supported by Guider, enter one of the following commands:
$ python3 guider/guider.py --help
$ python3 -m guider --help
$ guider --help
To start tracing for all threads, use the following command:
# python3 guider/guider.py rec -a
To start tracing for all threads, use the following command:
$ python3 guider/guider.py top -a
To view options and examples for each command, enter a command in the following format:
$ python3 guider/guider.py rec -h
$ python3 guider/guider.py top -h
To view the output of Guider, visit the following link:
- https://github.com/iipeace/guider/wiki
```
Build & Installation
=======
```
To install Guider using pip, enter the following commands:
# pip3 install guider
# pip3 install guider --no-deps
# pip3 install guider --force-reinstall
After installation, run one of the following commands to start Guider:
# python3 -m guider
# guider
If you don't have pip on your system, you can download the source code from https://github.com/iipeace/guider, and then run the following command to start Guider:
# python3 guider/guider.py
For faster and lighter operation, you can build and install Guider from the source code by running the following commands:
# cd guider && make && make install
```
Pre-built versions of Guider are available at https://repology.org/project/guider/versions.
Kernel Configuration
=======
```
Enable kernel options as below to take advantage of all profile features,
And if CONFIG_STRICT_MEMORY_RWX is enabled then disable it
CONFIG_RING_BUFFER
CONFIG_FTRACE
CONFIG_TRACING
CONFIG_TRACING_SUPPORT
CONFIG_EVENT_TRACING
CONFIG_NOP_TRACER
CONFIG_TRACEPOINTS
CONFIG_DYNAMIC_FTRACE
CONFIG_HAVE_DYNAMIC_FTRACE
CONFIG_FTRACE_SYSCALLS
CONFIG_HAVE_SYSCALL_TRACEPOINTS
CONFIG_TRACE_IRQFLAGS
CONFIG_TRACE_IRQFLAGS_SUPPORT
CONFIG_STACKTRACE
CONFIG_STACKTRACE_SUPPORT
CONFIG_USER_STACKTRACE_SUPPORT
CONFIG_FUNCTION_TRACER
CONFIG_FUNCTION_GRAPH_TRACER
CONFIG_UPROBES
CONFIG_UPROBE_EVENT
CONFIG_KPROBES
CONFIG_KPROBE_EVENTS
CONFIG_TASKSTATS
CONFIG_TASK_DELAY_ACCT
CONFIG_TASK_XACCT
CONFIG_TASK_IO_ACCOUNTING
CONFIG_PERF_EVENTS
CONFIG_HW_PERF_EVENT
```
Help
=======
```
Usage:
$ ./guider COMMAND [OPTIONS] [--help]
COMMAND(136):
[CONTROL] freeze (Linux)
hook (Linux)
kill/tkill (Linux/MacOS)
limitcpu (Linux)
limitcpuset (Linux)
limitmem (Linux)
limitpid (Linux)
limitread (Linux)
limitwrite (Linux)
pause (Linux)
remote (Linux)
rlimit (Linux)
setafnt (Linux)
setcpu (Linux)
setsched (Linux)
[LOG] logdlt (Linux)
logjrl (Linux)
logkmsg (Linux)
logsys (Linux)
printdlt (Linux/MacOS)
printjrl (Linux)
printkmsg (Linux)
printsys (Linux)
[MONITOR] atop (Linux)
bgtop (Linux/MacOS/Windows)
btop (Linux)
cgtop (Linux)
ctop (Linux/MacOS/Windows)
dbustop (Linux)
disktop (Linux/MacOS/Windows)
dlttop (Linux/MacOS)
fetop (Linux)
ftop (Linux/MacOS)
irqtop (Linux)
ktop (Linux)
mtop (Linux)
ntop (Linux/MacOS/Windows)
ptop (Linux)
pytop (Linux)
rtop (Linux/MacOS/Windows)
slabtop (Linux)
stacktop (Linux)
systop (Linux)
top (Linux/MacOS/Windows)
ttop (Linux)
utop (Linux)
vtop (Linux)
wtop (Linux)
[NETWORK] cli (Linux/MacOS/Windows)
event (Linux)
fserver (Linux/MacOS/Windows)
hserver (Linux/MacOS/Windows)
list (Linux/MacOS/Windows)
send (Linux/MacOS/Windows)
server (Linux/MacOS)
start (Linux)
[PROFILE] filerec (Linux)
funcrec (Linux)
genrec (Linux)
iorec (Linux)
mem (Linux)
rec (Linux)
report (Linux)
sysrec (Linux)
[TEST] cputest (Linux/MacOS/Windows)
iotest (Linux/MacOS/Windows)
memtest (Linux/MacOS/Windows)
nettest (Linux)
[TRACE] btrace (Linux)
leaktrace (Linux)
pytrace (Linux)
sigtrace (Linux)
strace (Linux)
utrace (Linux)
[UTIL] addr2sym (Linux/MacOS/Windows)
cgroup (Linux)
checkdup (Linux)
comp (Linux/MacOS/Windows)
decomp (Linux/MacOS/Windows)
dump (Linux)
exec (Linux/MacOS/Windows)
fadvise (Linux)
flush (Linux)
getafnt (Linux)
mkcache (Linux/MacOS/Windows)
mount (Linux)
ping (Linux/MacOS/Windows)
print (Linux/MacOS/Windows)
printbind (Linux)
printcg (Linux)
printdbus (Linux)
printdbusintro (Linux)
printdbusstat (Linux)
printdbussub (Linux)
printdir (Linux/MacOS/Windows)
printenv (Linux)
printext (Linux/MacOS/Windows)
printinfo (Linux)
printkconf (Linux)
printns (Linux)
printsdfile (Linux)
printsdinfo (Linux)
printsdunit (Linux)
printsig (Linux)
printslab (Linux)
printvma (Linux)
pstree (Linux/MacOS/Windows)
readahead (Linux)
readelf (Linux/MacOS/Windows)
req (Linux/MacOS/Windows)
strings (Linux/MacOS/Windows)
sym2addr (Linux/MacOS/Windows)
sync (Linux)
systat (Linux)
topdiff (Linux/MacOS/Windows)
topsum (Linux/MacOS/Windows)
umount (Linux)
watch (Linux)
[VISUAL] convert (Linux/MacOS/Windows)
draw (Linux/MacOS/Windows)
drawavg (Linux/MacOS/Windows)
drawbitmap (Linux/MacOS/Windows)
drawcpu (Linux/MacOS/Windows)
drawcpuavg (Linux/MacOS/Windows)
drawdelay (Linux/MacOS/Windows)
drawflame (Linux/MacOS/Windows)
drawio (Linux/MacOS/Windows)
drawleak (Linux/MacOS/Windows)
drawmem (Linux/MacOS/Windows)
drawmemavg (Linux/MacOS/Windows)
drawreq (Linux/MacOS/Windows)
drawrss (Linux/MacOS/Windows)
drawrssavg (Linux/MacOS/Windows)
drawtime (Linux/MacOS/Windows)
drawvss (Linux/MacOS/Windows)
drawvssavg (Linux/MacOS/Windows)
FILE:
Profile file (e.g. guider.dat)
Report file (e.g. guider.out)
Options:
Check COMMAND with --help (e.g. ./guider top --help)
```
././@PaxHeader 0000000 0000000 0000000 00000000034 00000000000 010212 x ustar 00 28 mtime=1675430767.9521296
guider-3.9.897/guider/ 0000755 0000000 0000000 00000000000 14367205560 013217 5 ustar 00root root ././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1603118621.0
guider-3.9.897/guider/__init__.py 0000644 0000000 0000000 00000000053 13743323035 015321 0 ustar 00root root from . import guider
__all__ = ['guider']
././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1603118621.0
guider-3.9.897/guider/__main__.py 0000644 0000000 0000000 00000000155 13743323035 015305 0 ustar 00root root import os
from .guider import main
# set main environment #
os.environ["ISMAIN"] = "True"
main(args=None)
././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1675165107.0
guider-3.9.897/guider/guider 0000755 0000000 0000000 00000002076 14366176663 014443 0 ustar 00root root #!/bin/sh
# Guider Launcher
#
# Copyright (c) 2016-2023 Peace Lee
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the Free
# Software Foundation; either version 2 of the License, or (at your option)
# any later version.
# export CMDLINE for Guider #
CMDLINE=$0
export CMDLINE
# check PYTHON variable #
if [ $PYTHON ]; then
exec $PYTHON -m guider "$@"
fi
# define PYTHON variable #
PYTHON=""
# check python binaries #
for cmd in python3 python python2
do
# check a python binary #
R=$(which $cmd 2> /dev/null)
if [ $? -ne "0" ]; then
continue;
fi
# set available python list #
PYTHON="$PYTHON$cmd "
# check guider module #
R=$($cmd -m guider)
if [ $? -ne "0" ]; then
continue;
fi
# launch Guider #
exec $cmd -m guider "$@"
done
# print error message #
if [ -z "$PYTHON" ]; then
echo "[Error] failed to find python"
else
echo "[Error] failed to find Guider module in $PYTHON"
fi
exit 1
././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1675429913.0
guider-3.9.897/guider/guider.conf 0000644 0000000 0000000 00000064076 14367204031 015352 0 ustar 00root root # Guider Configuration
'''
[ Threshold Description ]
- RESOURCE
- cpu: total, user, kernel, irq, iowait
- gpu: total
- mem: available, free, anon, file, slab, pgRclm, rss
- gpumem total, size
- swap: usagePer, swapOut
- block: iowait, read, write
- storage: usagePer, free, favail, readtime, writetime
- net: inbound, outbound, recv, trans
- load: 1m, 5m, 15m
- fd: curFd, fdSize
- sock: UDP, TCP, TCPCON, UDS
- file: big, less, exist, none
- task: nrCtx, new, die, abnormal
- log: DLT, kernel, journal, syslog
- func: native, syscall, python, D-Bus, signal
- psi: cpu, memory, io
- cgroup: cpu, throttle, memory, read, write
- TARGET
- SYSTEM: system resources
- TASK: task resources (except for Guider)
- DEVICE: device resources
- *NAME: ID/NAME for specific tasks, devices, events
- KERNEL: kernel message
- DLT: DLT message
- JOURNAL: systemd journal message
- SYSLOG: syslog message
- SYSCALL: syscall
- NATIVE: native function for C, C++, Rust, Go
- PYTHON: python function
- DBUS: D-Bus message
- SIGNAL: signal
- FIELD
< common >
- apply: activation value (true/false)
- perm: permission requirement (root)
- interval: duration condition for event (tick)
- taskmon: monitoring status for tasks (true/false)
- message: event message (string)
- explain: description (string)
- command: command set for event handling
- oneshot: one-time event handling value (true/false)
- refresh: restart timer for items disabled by oneshot (tick)
- goneshot: global oneshot value (true/false)
- lock: global lock value to handle the event exclusively (true/false)
- before: uptime condition for event handling
- after: uptime condition for event handling
- rbefore: runtime condition for event handling
- rafter: runtime condition for event handling
< cpu >
- total: total CPU usage for system/process/thread (%)
- user: user CPU usage for system (%)
- kernel: kernel CPU usage for system (%)
- irq: irq CPU usage for system (%)
- iowait: iowait time for system (%)
< gpu >
- total: total GPU usage for system (%)
< mem >
- available: available memory for system (MB/%)
- free: free memory for system (MB/%)
- anon: anonymous memory for system (MB/%)
- file: file cache for system (MB/%)
- slab: slab cache for system (MB/%)
- pgRclmBg: background reclaimed memory for system (PAGE)
- pgRclmFg: foreground reclaimed memory for system (PAGE)
- rss: Resident Set Size for process (MB/%)
< gpumem >
- total: system RAM usage for GPU (MB/%)
- size: per-process RAM usage for GPU (MB/%)
< swap >
- usagePer: swap usage for system (%)
- swapOut: swap-outed memory for process (MB)
< block >
- ioWait: I/O wait time for system (%)
- read: read size for process
- write: write size for process
< storage >
- usagePer: usage for system (%)
- free: free space (MB)
- favail: file number can be created
- readtime: read time (ms)
- writetime: write time (ms)
< net >
- inbound: RX size for system
- outbound: TX size for system
- recv: RX size for device
- trans: TX size for device
< load >
- load1m: loadavg for 1 Min
- load5m: loadavg for 5 Min
- load15m: loadavg for 15 Min
< fd >
- curFd: file handle number for system
- fdSize: file descriptor number for process
< sock >
- UDP: UDP socket number for system
- TCP: TCP socket number for system
- TCPCON: TCP(ESTABLISHED) socket number for system
- UDS: UDS number for system
< file >
- big: file size
- less: file size
- exist: file status (true/false)
- none: file status (true/false)
< task >
- nrCtx: context switching number for system/thread
- new: created task status (true/false)
- die: terminated task status (true/false)
- abnormal: abnormal task status (true/false)
< log >
- filter: log filter
< func >
- thread: target filter
- filter: function filter
- group: process grouping status (true/false)
- main: target only main thread (true/false)
< psi >
- some-avg10: delay average for 10 seconds for at least one task (%)
- some-avg60: delay average for 60 seconds for at least one task (%)
- some-avg300: delay average for 300 seconds for at least one task (%)
- some-diff: delay diff for at least one task (%)
- full-avg10: delay average for 10 seconds for all tasks simultaneously (%)
- full-avg60: delay average for 60 seconds for all tasks simultaneously (%)
- full-avg300: delay average for 300 seconds for all tasks simultaneously (%)
- full-diff: delay diff for all tasks simultaneously (%)
< cgroup >
- cpu: total CPU usage for control group (%)
- throttle: total CPU throttle for control group (%)
- memory: total memory usage for control group (MB)
- read: total block read for control group (MB)
- write: total block write for control group (MB)
- VARIABLE
- EVTNAME: event name
- EVTTIME: event time
- EVTUTCTIME: event time (UTC)
- EVTUPTIME: event uptime
- EVTPID: task PID
- SELFPID: Guider PID
- NUMRUN: run number
- NUMREP: report number
- PID: task PID (for top command)
- COMMAND (embedded)
- BUFFER{:SIZE}: resize the monitoring buffer
- CLEAR: clear the monitoring buffer
- DISABLE{:RESOURCE}: disable monitoring of the specific resource
- ENABLE{:RESOURCE}: enable monitoring of the specific resource
- FILTER{:ITEM}: set the task filter
- INTERVAL{:TIME}: change the monitoring interval
- PAUSE: pause all monitoring activities
- RELOAD{:PATH}: reload the threshold config
- RESTART: restart the process
- SAVE{:TIME@NAME}: save the monitoring results to the file from the past to some time thereafter
- SAVERAW{:TIME@NAME}: save the monitoring results composed only of raw data to the file from the past to some time thereafter
- STOP: stop the threshold monitoring
- CHARACTER
- #: ignore a line
- ''': ignore specific range
'''
{
"COMMAND": {
"CMD_NOTIFY_WARN": "GUIDER cli upstream:notify:WARN",
"CMD_TOP": "GUIDER top -o /tmp/guider_top_EVTNAME_EVTTIME.out -R 10 -Y c:15",
"CMD_FTOP": "GUIDER ftop -o /tmp/guider_top_EVTNAME_EVTTIME.out -a -R 1 -Y c:15",
"CMD_FTOP_PROC": "GUIDER ftop -o /tmp/guider_top_EVTNAME_EVTTIME.out -a -g EVTPID -R 1 -Y c:15",
"CMD_MTOP": "GUIDER mtop -o /tmp/guider_top_EVTNAME_EVTTIME.out -R 3 -Y c:15",
"CMD_FUNCREC": "GUIDER funcrec -s /tmp/guider_funcrec_EVTNAME_EVTTIME.dat -R 3",
"CMD_DISKTOP": "GUIDER disktop -R 3 -a -o /tmp/guider_block_EVTNAME_EVTTIME.out -Y c:15",
"CMD_DISKTOP_TOTAL": "GUIDER disktop -e T -R 3 -a -o /tmp/block_EVTNAME_EVTTIME.out -Y c:15",
"CMD_NETTOP": "GUIDER ntop -R 3 -o /tmp/guider_task_EVTNAME_EVTTIME.out -Y c:15",
"CMD_TTOP_PROC": "GUIDER ttop -g EVTPID -P -R 3 -o /tmp/guider_task_EVTNAME_EVTTIME.out -Y c:15",
"CMD_TTOP_CTX": "GUIDER ttop -S C:1 -R 2 -o /tmp/guider_task_EVTNAME_EVTTIME.out -Y c:15",
"CMD_TTOP_UTOP_ALL": "GUIDER ttop -g EVTPID -P -S c:1 -e E -R 1 -Q -c \"GUIDER utop -g PID -H -o /tmp/guider_utop_EVTNAME_EVTTIME_COMM_PID.out -R 5 -q LAZYCACHE\"",
"CMD_TTOP_UTOP_2": "GUIDER ttop -g EVTPID -P -S c:1 -e E -R 1 -Q -q NRTOPRANK:2 -c \"GUIDER utop -g PID -H -o /tmp/guider_utop_EVTNAME_EVTTIME_COMM_PID.out -R 5 -q LAZYCACHE\"",
"CMD_UTOP": "GUIDER utop -g EVTPID -H -o /tmp/guider_utop_EVTNAME_EVTTIME_COMM_PID.out -R 3",
"CMD_LEAK_1G": "GUIDER leaktrace -g EVTPID -T /tmp/libleaktracer.so -o /tmp/guider_leak_EVTNAME_EVTTIME.out -c 1g",
"CMD_LEAK_+200M": "GUIDER leaktrace -g EVTPID -T /tmp/libleaktracer.so -o /tmp/guider_leak_EVTNAME_EVTTIME.out -c +200m"
},
"cpu": {
"SYSTEM": [
{
"apply": "true",
"total": 95,
"interval": 5,
"after": "60s",
"taskmon": "true",
"oneshot": "true",
"refresh": 10,
"command": ["SAVE:5s"],
"message": "system CPU usage is high",
"explain": "save monitoring results until after 5 seconds"
},
{
"apply": "false",
"total": 99,
"interval": 5,
"perm": "root",
"lock": "true",
"command": ["CMD_TOP", "CMD_FUNCREC"],
"message": "system CPU usage is critical",
"explain": "monitor processes and trace functions for specific time"
}
],
"TASK": [
{
"apply": "false",
"total": 95,
"interval": 5,
"oneshot": "true",
"refresh": 30,
"lock": "true",
"perm": "root",
"except": ["b.out"],
"command": ["CMD_TTOP_PROC"],
"explain": "trace functions for threads using CPU in specific processes"
}
],
"yes": [
{
"apply": "false",
"total": 98,
"interval": 3,
"perm": "root",
"lock": "true",
"oneshot": "true",
"command": ["CMD_TTOP_UTOP_2"],
"explain": "trace functions for threads using CPU in specific processes"
}
]
},
"gpu": {
"DEVICE": {
"apply": "false",
"total": 95,
"interval": 10,
"taskmon": "true",
"command": ["SAVE:5s"],
"message": "system GPU usage is high",
"explain": "save monitoring results until after 5 seconds"
}
},
"mem": {
"SYSTEM": [
{
"apply": "true",
"available": 100,
"goneshot": "true",
"command": ["SAVERAW"],
"message": "system available memory is low"
},
{
"apply": "false",
"free": 100,
"oneshot": "true",
"refresh": 10,
"command": ["SAVERAW"],
"message": "system free memory is low"
},
{
"apply": "false",
"pgRclmBg": 102400,
"pgRclmFg": 1024,
"goneshot": "true",
"command": ["CMD_MTOP"],
"message": "system memory is reclaimed"
}
],
"TASK": {
"apply": "false",
"rss": 800,
"perm": "root",
"oneshot": "true",
"lock": "true",
"except": ["b.out"],
"command": ["CMD_LEAK_1G"],
"explain": "trace functions for specific processes consuming memory"
},
"a.out": {
"apply": "false",
"rss": 10,
"interval": 3,
"perm": "root",
"oneshot": "true",
"lock": "true",
"command": ["CMD_LEAK_+200M"],
"explain": "trace functions for specific processes consuming memory"
}
},
"gpumem": {
"SYSTEM": {
"apply": "false",
"total": 2048,
"oneshot": "true",
"command": ["CMD_MTOP"],
"message": "GPU memory usage is high"
},
"TASK": {
"apply": "false",
"size": 310,
"perm": "root",
"oneshot": "true",
"except": ["b.out"],
"command": ["SAVE:3s"],
"message": "GPU memory usage for the specific process is high"
},
"weston": {
"apply": "false",
"size": 500,
"perm": "root",
"oneshot": "true",
"command": ["SAVE:3s"],
"message": "GPU memory usage for the specific process is high"
}
},
"swap": {
"SYSTEM": {
"apply": "false",
"usagePer": 95,
"interval": 5,
"perm": "root",
"command": ["CMD_MTOP"],
"message": "system SWAP usage is high",
"explain": "trace system memory usage"
},
"TASK": {
"apply": "false",
"swap": 100,
"except": ["b.out"],
"command": ["CMD_MTOP"],
"explain": "trace task memory usage"
}
},
"block": {
"SYSTEM": {
"apply": "false",
"ioWait": 10,
"interval": 5,
"perm": "root",
"command": ["CMD_DISKTOP"],
"message": "system I/O is heavy",
"explain": "trace system storage usage"
},
"TASK": {
"apply": "false",
"read": "500M",
"write": "100M",
"perm": "root",
"interval": 2,
"except": ["b.out"],
"command": ["CMD_DISKTOP_TOTAL"],
"explain": "trace task I/O"
},
"a.out": {
"apply": "false",
"read": "500M",
"write": "100M",
"interval": 2,
"perm": "root",
"command": ["CMD_DISKTOP_TOTAL"],
"explain": "trace task I/O"
}
},
"storage": {
"SYSTEM": {
"apply": "false",
"usagePer": 95,
"interval": 3,
"oneshot": "true",
"perm": "root",
"command": ["CMD_DISKTOP"],
"message": "system storage usage is high",
"explain": "trace system storage usage"
},
"DEVICE": {
"apply": "false",
"usagePer": 99,
"free": 100,
"interval": 5,
"except": ["/dev/loop*"],
"perm": "root",
"oneshot": "true",
"command": ["CMD_DISKTOP"],
"explain": "trace storage usage for all devices"
},
"/dev/sda2": {
"apply": "false",
"usagePer": 99,
"free": 100,
"interval": 3,
"perm": "root",
"oneshot": "true",
"command": ["CMD_DISKTOP"],
"explain": "trace storage usage for the specific device"
}
},
"net": {
"SYSTEM": {
"apply": "false",
"inbound": "1G",
"outbound": "500M",
"interval": 3,
"perm": "root",
"command": ["CMD_NETTOP"],
"message": "system network usage is high",
"explain": "trace network usage for all devices"
},
"DEVICE": {
"apply": "false",
"recv": "1G",
"trans": "500M",
"interval": 3,
"except": ["lo"],
"perm": "root",
"command": ["CMD_NETTOP"],
"explain": "trace network usage for specific devices"
},
"enp7s0": {
"apply": "false",
"recv": "1G",
"trans": "1G",
"perm": "root",
"interval": 3,
"command": ["CMD_NETTOP"],
"explain": "trace network usage for the specific device"
}
},
"load": {
"SYSTEM": {
"apply": "false",
"load1m": 8,
"command": ["SAVE"],
"message": "system loadavg value is high",
"explain": "save monitoring results"
}
},
"fd": {
"SYSTEM": {
"apply": "false",
"curFd": 90000,
"perm": "root",
"oneshot": "true",
"command": ["CMD_FTOP"],
"explain": "monitor file descriptors for system"
},
"TASK": {
"apply": "false",
"fdSize": 10000,
"perm": "root",
"oneshot": "true",
"refresh": 100,
"command": ["CMD_FTOP_PROC"],
"except": ["*.out", "screen"],
"explain": "monitor file descriptors for specific tasks"
},
"a.out": {
"apply": "false",
"fdSize": 10000,
"perm": "root",
"oneshot": "true",
"command": ["CMD_FTOP_PROC"],
"explain": "monitor file descriptors for the specific task"
}
},
"sock": {
"SYSTEM": {
"apply": "false",
"interval": 5,
"nrUDPSock": 10000,
"nrTCPSock": 10000,
"nrTCPConn": 10000,
"nrUDSSock": 10000,
"perm": "root",
"oneshot": "true",
"command": ["CMD_FTOP"],
"explain": "monitor sockets for system"
}
},
"file": {
"/tmp/PEACE*": {
"apply": "false",
"exist": "true",
"perm": "root",
"oneshot": "true",
"command": ["SAVE"],
"explain": "save monitoring results"
},
"/tmp/OK": {
"apply": "false",
"none": "true",
"perm": "root",
"command": ["SAVE"],
"explain": "save monitoring results"
},
"/tmp/TEST": {
"apply": "false",
"big": "1M",
"oneshot": "true",
"perm": "root",
"command": ["SAVE"],
"explain": "save monitoring results"
},
"/tmp/TEST2": {
"apply": "false",
"less": "1K",
"oneshot": "true",
"perm": "root",
"command": ["SAVE"],
"explain": "save monitoring results"
}
},
"task": {
"SYSTEM": [
{
"apply": "false",
"nrCtx": 50000,
"command": ["CMD_TTOP_CTX"],
"explain": "trace context switching for tasks"
},
{
"apply": "false",
"new": "true",
"die": "true",
"abnormal": "true",
"command": ["CMD_TOP"],
"explain": "trace processes"
}
],
"TASK": {
"apply": "false",
"except": ["b.out", "kworker*"],
"nrCtx": 5000,
"command": ["SAVE:3s"],
"explain": "save monitoring results until after 3 seconds"
},
"a.out": {
"apply": "false",
"new": "true",
"die": "true",
"command": ["SAVE"],
"explain": "save monitoring results"
}
},
"log": {
"DLT": [
{
"apply": "false",
"filter": "*critical*+oops",
"oneshot": "true",
"command": ["SAVE:3s"],
"explain": "save monitoring results until after 3 seconds"
}
],
"KERNEL": [
{
"apply": "false",
"filter": "*critical*+oops",
"goneshot": "true",
"command": ["SAVE:3s"],
"explain": "save monitoring results until after 3 seconds"
}
],
"JOURNAL": [
{
"apply": "false",
"filter": "*critical*+oops",
"oneshot": "true",
"command": ["SAVE:3s"],
"explain": "save monitoring results until after 3 seconds"
}
],
"SYSLOG": [
{
"apply": "false",
"filter": "*critical*+oops",
"perm": "true",
"command": ["SAVE:3s"],
"explain": "save monitoring results until after 3 seconds"
}
]
},
"func": {
"NATIVE": [
{
"apply": "false",
"thread": "a.out",
"group": "true",
"filter": "write*+read",
"perm": "true",
"oneshot": "true",
"command": ["SAVE:3s"],
"explain": "save monitoring results until after 3 seconds"
}
],
"SYSCALL": [
{
"apply": "false",
"thread": "a.out",
"group": "false",
"filter": "write*+read",
"oneshot": "true",
"perm": "true",
"command": ["SAVE:3s"],
"explain": "save monitoring results until after 3 seconds"
}
],
"PYTHON": [
{
"apply": "false",
"thread": "iotop",
"main": "true",
"filter": "write*+read",
"perm": "true",
"oneshot": "true",
"command": ["SAVE:3s"],
"explain": "save monitoring results until after 3 seconds"
}
],
"DBUS": [
{
"apply": "false",
"thread": "dbus-daemon",
"filter": "*TestInterface*+*OnEmitSignal*",
"perm": "true",
"oneshot": "true",
"command": ["SAVE:3s"],
"explain": "save monitoring results until after 3 seconds"
}
],
"SIGNAL": [
{
"apply": "false",
"thread": "a.out",
"filter": "SIGINT+SIGSTOP",
"perm": "true",
"oneshot": "true",
"command": ["SAVE:3s"],
"explain": "save monitoring results until after 3 seconds"
}
]
},
"psi": {
"cpu": [
{
"apply": "false",
"some-avg10": 30,
"some-avg60": 30,
"some-avg300": 30,
"some-diff": 30,
"oneshot": "true",
"refresh": 100,
"command": ["SAVE:3s"],
"explain": "save monitoring results until after 3 seconds"
}
],
"memory": [
{
"apply": "false",
"some-avg10": 30,
"full-avg60": 30,
"full-avg300": 30,
"some-diff": 30,
"oneshot": "true",
"refresh": 100,
"command": ["SAVE:3s"],
"explain": "save monitoring results until after 3 seconds"
}
],
"io": [
{
"apply": "false",
"some-avg10": 30,
"full-avg60": 30,
"full-avg300": 30,
"some-diff": 30,
"oneshot": "true",
"refresh": 100,
"command": ["SAVE:3s"],
"explain": "save monitoring results until after 3 seconds"
}
]
},
"cgroup": {
"/": [
{
"apply": "false",
"interval": 3,
"cpu": 400,
"throttle": 100,
"command": ["SAVE"],
"explain": "save monitoring results"
},
{
"apply": "false",
"interval": 3,
"memory": 300,
"read": 600,
"write": 500,
"command": ["SAVE"],
"explain": "save monitoring results"
},
{
"apply": "false",
"interval": 2,
"read": 700,
"write": 500,
"command": ["SAVE"],
"explain": "save monitoring results"
}
]
}
}
'''
[ Server Description ]
- COMMAND: shortcut for commands
- INIT: commands executed remotely when connected
- apply: switch flag
- perm: requirement for permission
- interval: interval for repeatation (TBD)
- duration: condition for duration
- command: command set
- oneshot: oneshot flag (TBD)
- explain: description
- EVENT: event handlers
- name: event name
- apply: switch flag
- command: commands executed when the event occur
- handler: functions called when the event occur
- CHARACTER
- #: ignore a line
- ''': ignore specific range
'''
{
"COMMAND": {
"CMD_RTOP": "GUIDER rtop -Q -i 3 -C",
"CMD_DOWN": "download:/tmp/*@./backup/",
"CMD_MAIL": "mail -s \"Warning Report\" master@github.com"
},
"INIT": [
{
"apply": "false",
"perm": "none",
"oneshot": "true",
"duration": "10s",
"command": ["CMD_RTOP"],
"explain": "print system stat in JSON format from the new node to stdout"
},
{
"apply": "false",
"perm": "none",
"oneshot": "true",
"command": ["CMD_RTOP->cat"],
"explain": "deliver system stat in JSON format from the new node to the cat process in local machine through pipe"
},
{
"apply": "false",
"perm": "true",
"oneshot": "false",
"interval": "10s",
"command": ["CMD_DOWN"],
"explain": "download specific files from the new node every 10 seconds"
}
],
"EVENT": [
{
"name": "TEST",
"apply": "false",
"command": ["ls -lha", "CMD_MAIL"],
"handler": ["./test.py:test"],
"explain": "make a snapshot image for system"
}
]
}
'''
[ Auto Command Description ]
- CHARACTER
- #: ignore a line
- ''': ignore specific range
'''
{
"apply": "false",
"list": [
"GUIDER list",
"ls -lha"
]
}
././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1675429931.0
guider-3.9.897/guider/guider.py 0000775 0000000 0000000 00017454103 14367204053 015070 0 ustar 00root root #!/usr/bin/env python3
# -*- coding: utf-8 -*-
__author__ = "Peace Lee"
__copyright__ = "Copyright 2015-2023, Guider"
__module__ = "guider"
__credits__ = "Peace Lee"
__license__ = "GPLv2"
__version__ = "3.9.8"
__revision__ = "230203"
__maintainer__ = "Peace Lee"
__email__ = "iipeace5@gmail.com"
__repository__ = "https://github.com/iipeace/guider"
# import essential packages #
import sys
try:
import os
import re
import gc
import time
import errno
import signal
import atexit
import struct
from copy import deepcopy
# from ctypes import * # for lint check
except ImportError:
err = sys.exc_info()[1]
sys.exit("[ERROR] failed to import essential package: %s" % err.args[0])
# convert an unsupported type #
try:
long # pylint: disable=used-before-assignment
except:
long = int
# prevent MemoryError in python2 #
try:
xrange # pylint: disable=used-before-assignment
except:
xrange = range
# enable JIT compiler #
try:
if "JITCOMPILE" in os.environ:
from numba import jit # pylint: disable=import-error
else:
def jit(func):
def decorated():
func()
return decorated
except:
err = sys.exc_info()[1]
sys.exit("[ERROR] failed to import numba package: %s" % err.args[0])
class ConfigMgr(object):
"""Manager for config"""
# logo, made by http://www.figlet.org, consider also jp2a #
logo = """
_____ _ _
/ ____| (_) | |
| | __ _ _ _ __| | ___ _ __
| | |_ | | | | |/ _` |/ _ \ '__|
| |__| | |_| | | (_| | __/ |
\_____|\__,_|_|\__,_|\___|_| ver_%s_%s on python_%s.%s
""" % (
__version__,
__revision__,
sys.version_info[0],
sys.version_info[1],
)
# color #
if (
sys.platform.startswith("linux")
or sys.platform.startswith("darwin")
or sys.platform.startswith("freebsd")
) and not "REMOTERUN" in os.environ:
ENDC = "\033[0m"
else:
ENDC = ""
# config info #
confData = {}
# support architecture #
supportArch = ["arm", "aarch64", "x86", "x64"]
# ANSI color #
COLOR_LIST = {
"DEFAULT": "\033[0m",
"BOLD": "\033[1m",
"ITALIC": "\033[3m",
"UNDERLINE": "\033[4m",
"LIGHT": "\033[5m",
"BLINK": "\033[6m",
"REVERSE": "\033[7m",
"SCRATCH": "\033[9m",
"BLACK": "\033[30m",
"RED": "\033[31m",
"GREEN": "\033[32m",
"YELLOW": "\033[33m",
"BLUE": "\033[34m",
"PINK": "\033[35m",
"CYAN": "\033[36m",
"WHITE": "\033[37m",
"DEFCOLOR": "\033[39m",
"BGBLACK": "\033[40m",
"BGRED": "\033[41m",
"BGGREEN": "\033[42m",
"BGYELLOW": "\033[43m",
"BGBLUE": "\033[44m",
"BGPINK": "\033[45m",
"BGCYAN": "\033[46m",
"BGWHITE": "\033[47m",
"FAIL": "\033[91m",
"OKGREEN": "\033[92m",
"SPECIAL": "\033[93m",
"OKBLUE": "\033[94m",
"WARNING": "\033[95m",
"LIGHTGREEN": "\033[1;32m",
}
# cgroup entity #
CGROUP_VALUE = [
"tasks",
"cgroup.procs",
"cpu.shares",
"cpu.cfs_period_us",
"cpu.cfs_quota_us",
"cpu.rt_period_us",
"cpu.rt_runtime_us",
"cpu.stat",
"cpu.uclamp.min",
"cpu.uclamp.max",
"cpu.uclamp.latency_sensitive",
"cpuacct.usage",
"cpuset.cpus",
"cpus",
"memory.limit_in_bytes",
"memory.memsw.limit_in_bytes",
"blkio.weight",
"blkio.bfq.weight",
"blkio.weight_device",
"blkio.io_wait_time",
"blkio.throttle.io_service_bytes",
"cpu.pressure",
"memory.pressure",
"io.pressure",
]
# cgroup stat #
CGROUP_STAT = {
"blkio.throttle.io_service_bytes_recursive": None,
"cgroup.procs": None,
"cpu.stat": None,
"cpuacct.usage": None,
"memory.usage_in_bytes": None,
"tasks": None,
}
# state of process #
PROC_STAT_TYPE = {
"R": "running",
"S": "sleep",
"D": "disk",
"T": "stopped",
"t": "traced",
"X": "dead",
"x": "dead",
"Z": "zombie",
"K": "wakekill",
"W": "waking",
"P": "parked",
"I": "idle",
}
# diskstat statistics #
DISKSTAT = [
"major",
"minor",
"name",
"readComplete",
"readMerge",
"sectorRead",
"readTime",
"writeComplete",
"writeMerge",
"sectorWrite",
"writeTime",
"currentIO",
"ioTime",
"ioWTime",
"discComplete",
"discMerged",
"sectorDisc",
"discTime", # 4.18+
"flushComplete",
"flushTime", # 5.5+
]
BGRECLAIMSTAT = [
"pgsteal_kswapd",
"pgsteal_kswapd_normal",
"pgsteal_kswapd_high",
"pgsteal_kswapd_dma",
"pgsteal_kswapd_dma32",
"pgsteal_kswapd_movable",
]
FGRECLAIMSTAT = [
"pgsteal_direct",
"pgsteal_direct_normal",
"pgsteal_direct_high",
"pgsteal_direct_dma",
"pgsteal_direct_dma32",
"pgsteal_direct_movable",
]
# socketcall attributes #
SOCKETCALL = {
1: "socket",
2: "bind",
3: "connect",
4: "listen",
5: "accept",
6: "getsockname",
7: "getpeername",
8: "socketpair",
9: "send",
10: "recv",
11: "sendto",
12: "recvfrom",
13: "shutdown",
14: "setsockopt",
15: "getsockopt",
16: "sendmsg",
17: "recvmsg",
}
# socket family #
SOCKET_FAMILY = {
0: "AF_UNSPEC",
1: "AF_FILE",
2: "AF_INET",
3: "AF_AX25",
4: "AF_IPX",
5: "AF_APPLETALK",
6: "AF_NETROM",
7: "AF_BRIDGE",
8: "AF_ATMPVC",
9: "AF_X25",
10: "AF_INET6",
11: "AF_ROSE",
12: "AF_DECnet",
13: "AF_NETBEUI",
14: "AF_SECURITY",
15: "AF_KEY",
16: "AF_NETLINK",
17: "AF_PACKET",
18: "AF_ASH",
19: "AF_ECONET",
20: "AF_ATMSVC",
22: "AF_SNA",
23: "AF_IRDA",
24: "AF_PPPOX",
25: "AF_WANPIPE",
31: "AF_BLUETOOTH",
}
# DLOPEN type #
DLOPEN_TYPE = {
1: "RTLD_LAZY",
2: "RTLD_NOW",
3: "RTLD_BINDING_MASK",
4: "RTLD_NOLOAD",
8: "RTLD_DEEPBIND",
}
# socket type #
SOCKET_TYPE = {
1: "SOCK_STREAM",
2: "SOCK_DGRAM",
3: "SOCK_RAW",
4: "SOCK_RDM",
5: "SOCK_SEQPACKET",
10: "SOCK_PACKET",
}
# log level #
LOG_LEVEL = {
0: "EMERG",
1: "ALERT",
2: "CRIT",
3: "ERR",
4: "WARNING",
5: "NOTICE",
6: "INFO",
7: "DEBUG",
}
# MSG type #
MSG_TYPE = {
0x1: "MSG_OOB",
0x2: "MSG_PEEK",
0x4: "MSG_DONTROUTE|MSG_TRYHARD",
0x8: "MSG_CTRUNC",
0x10: "MSG_PROBE",
0x20: "MSG_TRUNC",
0x40: "MSG_DONTWAIT",
0x80: "MSG_EOR",
0x100: "MSG_WAITALL",
0x200: "MSG_FIN",
0x400: "MSG_SYN",
0x800: "MSG_CONFIRM",
0x1000: "MSG_RST",
0x2000: "MSG_ERRQUEUE",
0x4000: "MSG_NOSIGNAL",
0x8000: "MSG_MORE",
0x40000000: "MSG_CMSG_CLOEXEC",
0x80000000: "MSG_CMSG_COMPAT",
}
# control message type #
CMSG_TYPE = {
0x01: "SCM_RIGHTS", # rw: access rights (array of int)
0x02: "SCM_CREDENTIALS", # rw: struct ucred
0x03: "SCM_SECURITY",
}
# mmap prot type #
MAP_TYPE = {
0x0000: "MAP_FILE",
0x0001: "MAP_SHARED",
0x0002: "MAP_PRIVATE",
# 0x0003: "MAP_SHARED_VALIDATE",
# 0x000f: "MAP_TYPE",
0x0010: "MAP_FIXED",
0x0020: "MAP_ANONYMOUS",
0x0100: "MAP_GROWSDOWN",
0x0800: "MAP_DENYWRITE",
0x1000: "MAP_EXECUTABLE",
0x2000: "MAP_LOCKED",
0x4000: "MAP_NORESERVE",
0x8000: "MAP_POPULATE",
0x10000: "MAP_NONBLOCK",
0x20000: "MAP_STACK",
0x40000: "MAP_HUGETLB",
0x80000: "MAP_SYNC",
}
# FAT type #
FAT_TYPE = {
-100: "AT_FDCWD",
0x100: "AT_SYMLINK_NOFOLLOW",
0x200: "AT_REMOVEDIR",
0x400: "AT_SYMLINK_FOLLOW",
0x800: "AT_NO_AUTOMOUNT",
0x1000: "AT_EMPTY_PATH",
}
FAT_TYPE_REVERSE = {}
# mmap prot type #
PROT_TYPE = {
0x0: "PROT_NONE", # Page can not be accessed
0x1: "PROT_READ", # Page can be read
0x2: "PROT_WRITE", # Page can be written
0x4: "PROT_EXEC", # Page can be executed
}
# perm type #
PERM_TYPE = {0x0: "F_OK", 0x1: "X_OK", 0x2: "W_OK", 0x4: "R_OK"}
# seek type #
SEEK_TYPE = {0x0: "SEEK_SET", 0x1: "SEEK_CUR", 0x2: "SEEK_END"}
# prctl flags type #
PRCTL_TYPE = {
1: "PR_SET_PDEATHSIG",
2: "PR_GET_PDEATHSIG",
3: "PR_GET_DUMPABLE",
4: "PR_SET_DUMPABLE",
5: "PR_GET_UNALIGN",
6: "PR_SET_UNALIGN",
7: "PR_GET_KEEPCAPS",
8: "PR_SET_KEEPCAPS",
9: "PR_GET_FPEMU",
10: "PR_SET_FPEMU",
11: "PR_GET_FPEXC",
12: "PR_SET_FPEXC",
13: "PR_GET_TIMING",
14: "PR_SET_TIMING",
15: "PR_SET_NAME",
16: "PR_GET_NAME",
19: "PR_GET_ENDIAN",
20: "PR_SET_ENDIAN",
21: "PR_GET_SECCOMP",
22: "PR_SET_SECCOMP",
23: "PR_CAPBSET_READ",
24: "PR_CAPBSET_DROP",
25: "PR_GET_TSC 25",
26: "PR_SET_TSC 26",
27: "PR_GET_SECUREBITS",
28: "PR_SET_SECUREBITS",
29: "PR_SET_TIMERSLACK",
30: "PR_GET_TIMERSLACK",
31: "PR_TASK_PERF_EVENTS_DISABLE",
32: "PR_TASK_PERF_EVENTS_ENABLE",
33: "PR_MCE_KILL",
}
# mount flags type #
MOUNT_TYPE = {
"MS_RDONLY": 1, # Mount read-only
"MS_NOSUID": 2, # Ignore suid and sgid bits
"MS_NODEV": 4, # Disallow access to device special files
"MS_NOEXEC": 8, # Disallow program execution
"MS_SYNCHRONOUS": 16, # Writes are synced at once
"MS_REMOUNT": 32, # Alter flags of a mounted FS
"MS_MANDLOCK": 64, # Allow mandatory locks on an FS
"MS_WRITE": 128, # Write on file/directory/symlink
"MS_APPEND": 256, # Append-only file
"MS_IMMUTABLE": 512, # Immutable file
"MS_NOATIME": 1024, # Do not update access times
"MS_NODIRATIME": 2048, # Do not update directory access times
"MS_BIND": 4096, # Bind directory at different place
"MS_REC": 16384,
"MS_VERBOSE": 32768, # War is peace. Verbosity is silence
"MS_SILENT": 32768,
"MS_POSIXACL": (1 << 16), # VFS does not apply the umask
"MS_UNBINDABLE": (1 << 17), # change to unbindable
"MS_PRIVATE": (1 << 18), # change to private
"MS_SLAVE": (1 << 19), # change to slave
"MS_SHARED": (1 << 20), # change to shared
"MS_RELATIME": (1 << 21), # Update atime relative to mtime/ctime
"MS_KERNMOUNT": (1 << 22), # this is a kern_mount call
"MS_I_VERSION": (1 << 23), # Update inode I_version field
"MS_STRICTATIME": (1 << 24), # Always perform atime updates
"MS_LAZYTIME": (1 << 25), # Update the on-disk [acm]times lazily
"MS_NOSEC": (1 << 28),
"MS_BORN": (1 << 29),
"MS_ACTIVE": (1 << 30),
"MS_NOUSER": (1 << 31),
}
MOUNT_TYPE_REVERSE = {}
# umount flags type #
UMOUNT_TYPE = {
"MNT_FORCE": 0x00000001, # Attempt to forcibily umount
"MNT_DETACH": 0x00000002, # Just detach from the tree
"MNT_EXPIRE": 0x00000004, # Mark for expiry
"MNT_NOFOLLOW": 0x00000008, # Don't follow symlink on umount
"MNT_UNUSED": 0x80000000, # Flag guaranteed to be unused
}
UMOUNT_TYPE_REVERSE = {}
# clone flags type #
CLONE_TYPE = {
0x000000FF: "CSIGNAL",
0x00000100: "CLONE_VM",
0x00000200: "CLONE_FS",
0x00000400: "CLONE_FILES",
0x00000800: "CLONE_SIGHAND",
0x00002000: "CLONE_PTRACE",
0x00004000: "CLONE_VFORK",
0x00008000: "CLONE_PARENT",
0x00010000: "CLONE_THREAD",
0x00020000: "CLONE_NEWNS",
0x00040000: "CLONE_SYSVSEM",
0x00080000: "CLONE_SETTLS",
0x00100000: "CLONE_PARENT_SETTID",
0x00200000: "CLONE_CHILD_CLEARTID",
0x00400000: "CLONE_DETACHED",
0x00800000: "CLONE_UNTRACED",
0x01000000: "CLONE_CHILD_SETTID",
0x02000000: "CLONE_STOPPED",
0x04000000: "CLONE_NEWUTS",
0x08000000: "CLONE_NEWIPC",
0x10000000: "CLONE_NEWUSER",
0x20000000: "CLONE_NEWPID",
0x40000000: "CLONE_NEWNET",
0x80000000: "CLONE_IO",
}
# open flags type #
OPEN_TYPE = {
0o0: "O_RDONLY",
0o1: "O_WRONLY",
0o2: "O_RDWR",
0o100: "O_CREAT",
0o200: "O_EXCL",
0o400: "O_NOCTTY",
0o1000: "O_TRUNC",
0o2000: "O_APPEND",
0o4000: "O_NONBLOCK",
0o10000: "O_SYNC",
0o20000: "O_ASYNC",
0o40000: "O_DIRECT",
0o100000: "O_LARGEFILE",
0o200000: "O_DIRECTORY",
0o400000: "O_NOFOLLOW",
0o1000000: "O_NOATIME",
0o2000000: "O_CLOEXEC",
0o10000000: "O_PATH",
0o20200000: "O_TMPFILE",
}
# epoll op type #
EPOLL_CMD_TYPE = [
"EPOLL_CTL_NONE", # None
"EPOLL_CTL_ADD", # Add a file descriptor to the interface
"EPOLL_CTL_DEL", # Remove a file descriptor from the interface
"EPOLL_CTL_MOD", # Change file descriptor epoll_event structure
]
# epoll event type #
EPOLL_EVENT_TYPE = {
0x001: "EPOLLIN",
0x002: "EPOLLPRI",
0x004: "EPOLLOUT",
0x040: "EPOLLRDNORM",
0x080: "EPOLLRDBAND",
0x100: "EPOLLWRNORM",
0x200: "EPOLLWRBAND",
0x400: "EPOLLMSG",
0x008: "EPOLLERR",
0x010: "EPOLLHUP",
0x2000: "EPOLLRDHUP",
(1 << 29): "EPOLLWAKEUP",
(1 << 30): "EPOLLONESHOT",
(1 << 31): "EPOLLET",
}
# clock type #
CLOCK_TYPE = {
"CLOCK_REALTIME": 0, # Identifier for system-wide realtime clock
"CLOCK_MONOTONIC": 1, # Monotonic system-wide clock
"CLOCK_PROCESS_CPUTIME_ID": 2, # High-resolution timer from the CPU
"CLOCK_THREAD_CPUTIME_ID": 3, # Thread-specific CPU-time clock
"CLOCK_BOOTTIME": 7, # Monotonic system-wide clock that includes time spent in suspension
"CLOCK_REALTIME_ALARM": 8, # Like CLOCK_REALTIME but also wakes suspended system
"CLOCK_BOOTTIME_ALARM": 9, # CLOCK_BOOTTIME but also wakes suspended system
"CLOCK_TAI": 11, # Like CLOCK_REALTIME but in International Atomic Time
}
# fadvise type #
FADV_TYPE = {
0: "FADV_NORMAL", # No further special treatment
1: "FADV_RANDOM", # Expect random page references
2: "FADV_SEQUENTIAL", # Expect sequential page references
3: "FADV_WILLNEED", # Will need these pages
4: "FADV_DONTNEED", # Don't need these pages
5: "FADV_NOREUSE", # Data will be accessed once
# 6: "FADV_DONTNEED", # Don't need these pages
# 7: "FADV_NOREUSE", # Data will be accessed once
}
FADV_TYPE_REVERSE = {}
# madvise type #
MADV_TYPE = {
0: "MADV_NORMAL", # No further special treatment
1: "MADV_RANDOM", # Expect random page references
2: "MADV_SEQUENTIAL", # Expect sequential page references
3: "MADV_WILLNEED", # Will need these pages
4: "MADV_DONTNEED", # Don't need these pages
8: "MADV_FREE", # Free pages only if memory pressure
9: "MADV_REMOVE", # Remove these pages and resources
10: "MADV_DONTFORK", # Do not inherit across fork
11: "MADV_DOFORK", # Do inherit across fork
12: "MADV_MERGEABLE", # KSM may merge identical pages
13: "MADV_UNMERGEABLE", # KSM may not merge identical pages
14: "MADV_HUGEPAGE", # Worth backing with hugepages
15: "MADV_NOHUGEPAGE", # Not worth backing with hugepages
16: "MADV_DONTDUMP", # Explicitly exclude from the core dump,
17: "MADV_DODUMP", # Clear the MADV_DONTDUMP flag
18: "MADV_WIPEONFORK", # Zero memory on fork, child only
19: "MADV_KEEPONFORK", # Undo MADV_WIPEONFORK
20: "MADV_COLD", # Deactivatie these pages
21: "MADV_PAGEOUT", # Reclaim these pages
100: "MADV_HWPOISON", # Poison a page for testing
}
MADV_TYPE_REVERSE = {}
# fanotify types #
FAN_EVENT_TYPE = {
0x00000001: "FAN_ACCESS", # File was accessed #
0x00000002: "FAN_MODIFY", # File was modified #
0x00000004: "FAN_ATTRIB", # Metadata changed #
0x00000008: "FAN_CLOSE_WRITE", # Writtable file closed #
0x00000010: "FAN_CLOSE_NOWRITE", # Unwrittable file closed #
0x00000020: "FAN_OPEN", # File was opened #
0x00000040: "FAN_MOVED_FROM", # File was moved from X #
0x00000080: "FAN_MOVED_TO", # File was moved to Y #
0x00000100: "FAN_CREATE", # Subfile was created #
0x00000200: "FAN_DELETE", # Subfile was deleted #
0x00000400: "FAN_DELETE_SELF", # Self was deleted #
0x00000800: "FAN_MOVE_SELF", # Self was moved #
0x00001000: "FAN_OPEN_EXEC", # File was opened for exec #
0x00004000: "FAN_Q_OVERFLOW", # Event queued overflowed #
0x00010000: "FAN_OPEN_PERM", # File open in perm check #
0x00020000: "FAN_ACCESS_PERM", # File accessed in perm check #
0x00040000: "FAN_OPEN_EXEC_PERM", # File open/exec in perm check #
0x40000000: "FAN_ONDIR", # event occurred against dir #
0x08000000: "FAN_EVENT_ON_CHILD", # interested in child events #
}
FAN_EVENT_TYPE_REVERSE = {}
FAN_INIT_TYPE = {
0x00000000: "FAN_CLASS_NOTIF",
0x00000001: "FAN_CLOEXEC",
0x00000002: "FAN_NONBLOCK",
0x00000004: "FAN_CLASS_CONTENT",
0x00000008: "FAN_CLASS_PRE_CONTENT",
0x00000010: "FAN_UNLIMITED_QUEUE",
0x00000020: "FAN_UNLIMITED_MARKS",
0x00000040: "FAN_ENABLE_AUDIT",
0x00000100: "FAN_REPORT_TID",
0x00000200: "FAN_REPORT_FID",
0x00000800: "FAN_REPORT_NAME",
0x00001000: "FAN_REPORT_TARGET_FID",
}
FAN_INIT_TYPE_REVERSE = {}
"""
FAN_REPORT_DFID_NAME = FAN_REPORT_NAME | FAN_REPORT_DIR_FID
FAN_REPORT_DFID_NAME_TARGET = \
FAN_REPORT_DFID_NAME | FAN_REPORT_FID | FAN_REPORT_TARGETFID
"""
FAN_MARK_TYPE = {
0x00000000: "FAN_MARK_INODE",
0x00000001: "FAN_MARK_ADD",
0x00000002: "FAN_MARK_REMOVE",
0x00000004: "FAN_MARK_DONT_FOLLOW",
0x00000008: "FAN_MARK_ONLYDIR",
0x00000010: "FAN_MARK_MOUNT",
0x00000020: "FAN_MARK_IGNORED_MASK",
0x00000040: "FAN_MARK_IGNORED_SURV_MODIFY",
0x00000080: "FAN_MARK_FLUSH",
0x00000100: "FAN_MARK_FILESYSTEM",
}
FAN_PERM_TYPE = {
0x01: "FAN_ALLOW",
0x02: "FAN_DENY",
0x10: "FAN_AUDIT",
}
# netlink type #
NETLINK_TYPE = {
"NETLINK_ROUTE": 0,
"NETLINK_UNUSED": 1,
"NETLINK_USERSOCK": 2,
"NETLINK_FIREWALL": 3,
"NETLINK_SOCK_DIAG": 4,
"NETLINK_NFLOG": 5,
"NETLINK_XFRM": 6,
"NETLINK_SELINUX": 7,
"NETLINK_ISCSI": 8,
"NETLINK_AUDIT": 9,
"NETLINK_FIB_LOOKUP": 10,
"NETLINK_CONNECTOR": 11,
"NETLINK_NETFILTER": 12,
"NETLINK_IP6_FW": 13,
"NETLINK_DNRTMSG": 14,
"NETLINK_KOBJECT_UEVENT": 15,
"NETLINK_GENERIC": 16,
"NETLINK_SCSITRANSPORT": 18,
"NETLINK_ECRYPTFS": 19,
"NETLINK_RDMA": 20,
"NETLINK_CRYPTO": 21,
}
# entry type #
INOTIFY_TYPE = {
"IN_ACCESS": 0x00000001, # File was accessed */
"IN_MODIFY": 0x00000002, # File was modified */
"IN_ATTRIB": 0x00000004, # Metadata changed */
"IN_CLOSE_WRITE": 0x00000008, # Writtable file was closed */
"IN_CLOSE_NOWRITE": 0x00000010, # Unwrittable file closed */
"IN_CLOSE": 0x00000008 | 0x00000010, # file closed */
"IN_OPEN": 0x00000020, # File was opened */
"IN_MOVED_FROM": 0x00000040, # File was moved from X */
"IN_MOVED_TO": 0x00000080, # File was moved to Y */
"IN_MOVED": 0x00000040 | 0x00000080, # File was moved */
"IN_CREATE": 0x00000100, # Subfile was created */
"IN_DELETE": 0x00000200, # Subfile was deleted */
"IN_DELETE_SELF": 0x00000400, # Self was deleted */
"IN_MOVE_SELF": 0x00000800, # Self was moved */
"IN_UNMOUNT": 0x00002000, # Backing fs was unmounted */
"IN_Q_OVERFLOW": 0x00004000, # Event queued overflowed */
"IN_IGNORED": 0x00008000, # File was ignored */
"IN_ONLYDIR": 0x01000000, # only watch the path if it is a directory */
"IN_DONT_FOLLOW": 0x02000000, # don't follow a sym link */
"IN_EXCL_UNLINK": 0x04000000, # exclude events on unlinked objects */
"IN_MASK_CREATE": 0x10000000, # only create watches */
"IN_MASK_ADD": 0x20000000, # add to the mask of an already existing watch */
"IN_ISDIR": 0x40000000, # event occurred against dir */
"IN_ONESHOT": 0x80000000, # only send event once */
}
# entry type #
AT_TYPE = {
"AT_IGNORE": 1, # Entry should be ignored
"AT_EXECFD": 2, # File descriptor of program
"AT_PHDR": 3, # Program headers for program
"AT_PHENT": 4, # Size of program header entry
"AT_PHNUM": 5, # Number of program headers
"AT_PAGESZ": 6, # System page size
"AT_BASE": 7, # Base address of interpreter
"AT_FLAGS": 8, # Flags
"AT_ENTRY": 9, # Entry point of program
"AT_NOTELF": 10, # Program is not ELF
"AT_UID": 11, # Real uid
"AT_EUID": 12, # Effective uid
"AT_GID": 13, # Real gid
"AT_EGID": 14, # Effective gid
"AT_CLKTCK": 17, # Frequency of times()
"AT_PLATFORM": 15, # String identifying platform
"AT_HWCAP": 16, # Machine-dependent hints about
"AT_FPUCW": 18, # Used FPU control word
"AT_DCACHEBSIZE": 19, # Data cache block size
"AT_ICACHEBSIZE": 20, # Instruction cache block size
"AT_UCACHEBSIZE": 21, # Unified cache block size
"AT_IGNOREPPC": 22, # Entry should be ignored
"AT_SECURE": 23, # Boolean, was exec setuid-like?
"AT_BASE_PLATFORM": 24, # String identifying real platforms
"AT_RANDOM": 25, # Address of 16 random bytes
"AT_HWCAP2": 26, # More machine-dependent hints about
"AT_EXECFN": 31, # Filename of executable
"AT_SYSINFO": 32,
"AT_SYSINFO_EHDR": 33,
"AT_L1I_CACHESHAPE": 34,
"AT_L1D_CACHESHAPE": 35,
"AT_L2_CACHESHAPE": 36,
"AT_L3_CACHESHAPE": 37,
"AT_L1I_CACHESIZE": 40,
"AT_L1I_CACHEGEOMETRY": 41,
"AT_L1D_CACHESIZE": 42,
"AT_L1D_CACHEGEOMETRY": 43,
"AT_L2_CACHESIZE": 44,
"AT_L2_CACHEGEOMETRY": 45,
"AT_L3_CACHESIZE": 46,
"AT_L3_CACHEGEOMETRY": 47,
"AT_MINSIGSTKSZ": 51, # Stack needed for signal delivery
}
# syscall prototypes #
SYSCALL_REFBUF = {
"write": 0,
"read": 0,
"send": 0,
"sendto": 0,
"recv": 0,
"recvfrom": 0,
"pread": 0,
"pread64": 0,
"pwrite": 0,
"pwrite64": 0,
}
# BPF syscall commands #
BPF_CMD = [
"BPF_MAP_CREATE",
"BPF_MAP_LOOKUP_ELEM",
"BPF_MAP_UPDATE_ELEM",
"BPF_MAP_DELETE_ELEM",
"BPF_MAP_GET_NEXT_KEY",
"BPF_PROG_LOAD",
"BPF_OBJ_PIN",
"BPF_OBJ_GET",
"BPF_PROG_ATTACH",
"BPF_PROG_DETACH",
"BPF_PROG_TEST_RUN",
"BPF_PROG_GET_NEXT_ID",
"BPF_MAP_GET_NEXT_ID",
"BPF_PROG_GET_FD_BY_ID",
"BPF_MAP_GET_FD_BY_ID",
"BPF_OBJ_GET_INFO_BY_FD",
]
BPF_MAP_TYPE = [
"BPF_MAP_TYPE_UNSPEC",
"BPF_MAP_TYPE_HASH",
"BPF_MAP_TYPE_ARRAY",
"BPF_MAP_TYPE_PROG_ARRAY",
"BPF_MAP_TYPE_PERF_EVENT_ARRAY",
"BPF_MAP_TYPE_PERCPU_HASH",
"BPF_MAP_TYPE_PERCPU_ARRAY",
"BPF_MAP_TYPE_STACK_TRACE",
"BPF_MAP_TYPE_CGROUP_ARRAY",
"BPF_MAP_TYPE_LRU_HASH",
"BPF_MAP_TYPE_LRU_PERCPU_HASH",
"BPF_MAP_TYPE_LPM_TRIE",
"BPF_MAP_TYPE_ARRAY_OF_MAPS",
"BPF_MAP_TYPE_HASH_OF_MAPS",
"BPF_MAP_TYPE_DEVMAP",
"BPF_MAP_TYPE_SOCKMAP",
]
BPF_PROG_TYPE = [
"BPF_PROG_TYPE_UNSPEC",
"BPF_PROG_TYPE_SOCKET_FILTER",
"BPF_PROG_TYPE_KPROBE",
"BPF_PROG_TYPE_SCHED_CLS",
"BPF_PROG_TYPE_SCHED_ACT",
"BPF_PROG_TYPE_TRACEPOINT",
"BPF_PROG_TYPE_XDP",
"BPF_PROG_TYPE_PERF_EVENT",
"BPF_PROG_TYPE_CGROUP_SKB",
"BPF_PROG_TYPE_CGROUP_SOCK",
"BPF_PROG_TYPE_LWT_IN",
"BPF_PROG_TYPE_LWT_OUT",
"BPF_PROG_TYPE_LWT_XMIT",
"BPF_PROG_TYPE_SOCK_OPS",
"BPF_PROG_TYPE_SK_SKB",
]
BPF_ATTACH_TYPE = [
"BPF_CGROUP_INET_INGRESS",
"BPF_CGROUP_INET_EGRESS",
"BPF_CGROUP_INET_SOCK_CREATE",
"BPF_CGROUP_SOCK_OPS",
"BPF_SK_SKB_STREAM_PARSER",
"BPF_SK_SKB_STREAM_VERDICT",
"__MAX_BPF_ATTACH_TYPE",
]
# regset types #
NT_TYPE = {
"NT_PRSTATUS": 1,
"NT_PRFPREG": 2,
"NT_PRPSINFO": 3,
"NT_TASKSTRUCT": 4,
"NT_AUXV": 6,
"NT_SIGINFO": 0x53494749,
"NT_FILE": 0x46494C45,
"NT_PRXFPREG": 0x46E62B7F,
"NT_ARM_VFP": 0x400,
"NT_ARM_TLS": 0x401,
"NT_ARM_HW_BREAK": 0x402,
"NT_ARM_HW_WATCH": 0x403,
"NT_ARM_SYSTEM_CALL": 0x404,
}
# unpack types #
UNPACK_TYPE = {
"U1": "B",
"U2": "H",
"U4": "I",
"U8": "Q",
"S1": "b",
"S2": "h",
"S4": "i",
"S8": "q",
"float": "f",
"double": "d",
}
# syscall prototypes #
SYSCALL_DEFFERABLE = {
"clock_gettime": 0,
"clone": 0,
"getgroups": 0,
"getgroups16": 0,
"gethostname": 0,
"getitimer": 0,
"getpeername": 0,
"getsockname": 0,
"gettimeofday": 0,
"io_uring_setup": 0,
"pread": 0,
"pread64": 0,
"process_vm_readv": 0,
"read": 0,
"readlink": 0,
"readv": 0,
"recv": 0,
"recvfrom": 0,
"recvmmsg": 0,
"recvmsg": 0,
}
# syscall prototypes #
SYSCALL_PROTOTYPES = {
"accept": (
"long",
(
("int", "sockfd"),
("struct sockaddr *", "addr"),
("int *", "addrlen"),
),
),
"accept4": (
"long",
(
("int", "sockfd"),
("struct sockaddr *", "addr"),
("int *", "addrlen"),
("int", "flags"),
),
),
"access": ("long", (("const char *", "filename"), ("int", "mode"))),
"acct": ("long", (("const char *", "name"),)),
"add_key": (
"long",
(
("const char *", "_type"),
("const char *", "_description"),
("const void *", "_payload"),
("size_t", "plen"),
("key_serial_t", "destringid"),
),
),
"adjtimex": ("long", (("struct timex *", "txc_p"),)),
"alarm": ("long", (("unsigned int", "seconds"),)),
"bdflush": ("long", (("int", "func"), ("long", "data"))),
"bind": (
"long",
(
("int", "sockfd"),
("struct sockaddr *", "addr"),
("int", "addrlen"),
),
),
"bpf": (
"long",
(
("int", "cmd"),
("union bpf_attr *", "attr"),
("unsigned int", "size"),
),
),
"brk": ("long", (("unsigned long", "brk"),)),
"capget": (
"long",
(("cap_user_header_t", "header"), ("cap_user_data_t", "dataptr")),
),
"capset": (
"long",
(
("cap_user_header_t", "header"),
("const cap_user_data_t", "data"),
),
),
"chdir": ("long", (("const char *", "filename"),)),
"chmod": ("long", (("const char *", "filename"), ("umode_t", "mode"))),
"chown": (
"long",
(
("const char *", "filename"),
("uid_t", "user"),
("gid_t", "group"),
),
),
"chown16": (
"long",
(
("const char *", "filename"),
("old_uid_t", "user"),
("old_gid_t", "group"),
),
),
"chroot": ("long", (("const char *", "filename"),)),
"clock_adjtime": (
"long",
(("clockid_t", "which_clock"), ("struct timex *", "tx")),
),
"clock_adjtime32": (
"long",
(("clockid_t", "which_clock"), ("struct old_timex32 *", "tx")),
),
"clock_getres": (
"long",
(("clockid_t", "which_clock"), ("struct timespec *", "tp")),
),
"clock_getres_time32": (
"long",
(("clockid_t", "which_clock"), ("struct old_timespec32 *", "tp")),
),
"clock_gettime": (
"long",
(("clockid_t", "which_clock"), ("struct timespec *", "tp")),
),
"clock_gettime32": (
"long",
(("clockid_t", "which_clock"), ("struct old_timespec32 *", "tp")),
),
"clock_nanosleep": (
"long",
(
("clockid_t", "which_clock"),
("int", "flags"),
("const struct timespec *", "rqtp"),
("struct timespec *", "rmtp"),
),
),
"clock_nanosleep_time32": (
"long",
(
("clockid_t", "which_clock"),
("int", "flags"),
("struct old_timespec32 *", "rqtp"),
("struct old_timespec32 *", "rmtp"),
),
),
"clock_settime": (
"long",
(("clockid_t", "which_clock"), ("const struct timespec *", "tp")),
),
"clock_settime32": (
"long",
(("clockid_t", "which_clock"), ("struct old_timespec32 *", "tp")),
),
"clone": (
"long",
(
("unsigned long", "flags"),
("unsigned long", "child_stack"),
("int *", "ptid"),
("int *", "ctid"),
("unsigned long", "regs"),
),
),
"clone3": (
"long",
(("struct clone_args *", "uargs"), ("size_t", "size")),
),
"close": ("long", (("unsigned int", "fd"),)),
"close_range": (
"long",
(
("unsigned int", "fd"),
("unsigned int", "max_fd"),
("unsigned int", "flags"),
),
),
"connect": (
"long",
(
("int", "sockfd"),
("struct sockaddr *", "addr"),
("int", "addrlen"),
),
),
"copy_file_range": (
"long",
(
("int", "fd_in"),
("loff_t *", "off_in"),
("int", "fd_out"),
("loff_t *", "off_out"),
("size_t", "len"),
("unsigned int", "flags"),
),
),
"creat": ("long", (("const char *", "pathname"), ("umode_t", "mode"))),
"creat_module": ("long", (("const char *", "name"), ("int", "size"))),
"delete_module": (
"long",
(("const char *", "name_user"), ("unsigned int", "flags")),
),
"dup": ("long", (("unsigned int", "fildes"),)),
"dup2": (
"long",
(("unsigned int", "oldfd"), ("unsigned int", "newfd")),
),
"dup3": (
"long",
(
("unsigned int", "oldfd"),
("unsigned int", "newfd"),
("int", "flags"),
),
),
"epoll_create": ("long", (("int", "size"),)),
"epoll_create1": ("long", (("int", "flags"),)),
"epoll_ctl": (
"long",
(
("int", "epfd"),
("int", "op"),
("int", "fd"),
("struct epoll_event *", "event"),
),
),
"epoll_pwait": (
"long",
(
("int", "epfd"),
("struct epoll_event *", "events"),
("int", "maxevents"),
("int", "timeout"),
("const sigset_t *", "sigmask"),
("size_t", "sigsetsize"),
),
),
"epoll_wait": (
"long",
(
("int", "epfd"),
("struct epoll_event *", "events"),
("int", "maxevents"),
("int", "timeout"),
),
),
"eventfd": ("long", (("unsigned int", "count"),)),
"eventfd2": ("long", (("unsigned int", "count"), ("int", "flags"))),
"execve": (
"long",
(
("const char *", "filename"),
("const char * const *", "argv"),
("const char * const *", "envp"),
),
),
"execveat": (
"long",
(
("int", "dfd"),
("const char *", "filename"),
("const char * const *", "argv"),
("const char * const *", "envp"),
("int", "flags"),
),
),
"exit": ("long", (("int", "error_code"),)),
"exit_group": ("long", (("int", "error_code"),)),
"faccessat": (
"long",
(("int", "dfd"), ("const char *", "filename"), ("int", "mode")),
),
"faccessat2": (
"long",
(
("int", "dfd"),
("const char *", "filename"),
("int", "mode"),
("int", "flags"),
),
),
"fadvise64": (
"long",
(
("int", "fd"),
("loff_t", "offset"),
("size_t", "len"),
("int", "advice"),
),
),
"fadvise64_64": (
"long",
(
("int", "fd"),
("loff_t", "offset"),
("loff_t", "len"),
("int", "advice"),
),
),
"fallocate": (
"long",
(
("int", "fd"),
("int", "mode"),
("loff_t", "offset"),
("loff_t", "len"),
),
),
"fanotify_init": (
"long",
(("unsigned int", "flags"), ("unsigned int", "event_f_flags")),
),
"fanotify_mark": (
"long",
(
("int", "fanotify_fd"),
("unsigned int", "flags"),
("u64", "mask"),
("int", "dirfd"),
("const char *", "pathname"),
),
),
"fchdir": ("long", (("unsigned int", "fd"),)),
"fchmod": ("long", (("unsigned int", "fd"), ("umode_t", "mode"))),
"fchmodat": (
"long",
(
("int", "dfd"),
("const char *", "filename"),
("umode_t", "mode"),
),
),
"fchown": (
"long",
(("unsigned int", "fd"), ("uid_t", "user"), ("gid_t", "group")),
),
"fchown16": (
"long",
(
("unsigned int", "fd"),
("old_uid_t", "user"),
("old_gid_t", "group"),
),
),
"fchownat": (
"long",
(
("int", "dfd"),
("const char *", "filename"),
("uid_t", "user"),
("gid_t", "group"),
("int", "flag"),
),
),
"fcntl": (
"long",
(
("unsigned int", "fd"),
("unsigned int", "cmd"),
("unsigned long", "arg"),
),
),
"fcntl64": (
"long",
(
("unsigned int", "fd"),
("unsigned int", "cmd"),
("unsigned long", "arg"),
),
),
"fdatasync": ("long", (("unsigned int", "fd"),)),
"fgetxattr": (
"long",
(
("int", "fd"),
("const char *", "name"),
("void *", "value"),
("size_t", "size"),
),
),
"finit_module": (
"long",
(("int", "fd"), ("const char *", "uargs"), ("int", "flags")),
),
"flistxattr": (
"long",
(("int", "fd"), ("const char *", "list"), ("size_t", "size")),
),
"flock": ("long", (("unsigned int", "fd"), ("unsigned int", "cmd"))),
"fork": ("long", ()),
"fremovexattr": ("long", (("int", "fd"), ("const char *", "name"))),
"fsconfig": (
"long",
(
("int", "fs_fd"),
("unsigned int", "cmd"),
("const char *", "key"),
("const void *", "value"),
("int", "aux"),
),
),
"fsetxattr": (
"long",
(
("int", "fd"),
("const char *", "name"),
("const void *", "value"),
("size_t", "size"),
("int", "flags"),
),
),
"fsmount": (
"long",
(
("int", "fs_fd"),
("unsigned int", "flags"),
("unsigned int", "ms_flags"),
),
),
"fsopen": (
"long",
(("const char *", "fs_name"), ("unsigned int", "flags")),
),
"fspick": (
"long",
(
("int", "dfd"),
("const char *", "path"),
("unsigned int", "flags"),
),
),
"fstat": (
"long",
(
("unsigned int", "fd"),
("struct __old_kernel_stat *", "statbuf"),
),
),
"fstat64": (
"long",
(("unsigned long", "fd"), ("struct stat64 *", "statbuf")),
),
"fstatat64": (
"long",
(
("int", "dfd"),
("const char *", "filename"),
("struct stat64 *", "statbuf"),
("int", "flag"),
),
),
"fstatfs": (
"long",
(("unsigned int", "fd"), ("struct statfs *", "buf")),
),
"fstatfs64": (
"long",
(
("unsigned int", "fd"),
("size_t", "sz"),
("struct statfs64 *", "buf"),
),
),
"fsync": ("long", (("unsigned int", "fd"),)),
"ftruncate": (
"long",
(("unsigned int", "fd"), ("unsigned long", "length")),
),
"ftruncate64": (
"long",
(("unsigned int", "fd"), ("loff_t", "length")),
),
"futex": (
"long",
(
("u32 *", "uaddr"),
("int", "op"),
("u32", "val"),
("struct timespec *", "utime"),
("u32 *", "uaddr2"),
("u32", "val3"),
),
),
"futex_time32": (
"long",
(
("u32 *", "uaddr"),
("int", "op"),
("u32", "val"),
("struct old_timespec32 *", "utime"),
("u32 *", "uaddr2"),
("u32", "val3"),
),
),
"futimesat": (
"long",
(
("int", "dfd"),
("const char *", "filename"),
("struct old_timeval *", "utimes"),
),
),
"futimesat_time32": (
"long",
(
("unsigned int", "dfd"),
("const char *", "filename"),
("struct old_timeval32 *", "t"),
),
),
"get_kernel_syms": ("long", (("struct kernel_sym *", "table"))),
"get_mempolicy": (
"long",
(
("int *", "policy"),
("unsigned long *", "nmask"),
("unsigned long", "maxnode"),
("unsigned long", "addr"),
("unsigned long", "flags"),
),
),
"get_robust_list": (
"long",
(
("int", "pid"),
("struct robust_list_head * *", "head_ptr"),
("size_t *", "len_ptr"),
),
),
"get_thread_area": ("long", (("struct user_desc *", "u_info"))),
"getcpu": (
"long",
(
("unsigned *", "cpu"),
("unsigned *", "node"),
("struct getcpu_cache *", "cache"),
),
),
"getcwd": (
"long",
(("char *", "pathname"), ("unsigned long", "size")),
),
"getdents": (
"long",
(
("unsigned int", "fd"),
("struct linux_dirent *", "dirent"),
("unsigned int", "count"),
),
),
"getdents64": (
"long",
(
("unsigned int", "fd"),
("struct linux_dirent64 *", "dirent"),
("unsigned int", "count"),
),
),
"getegid": ("long", ()),
"getegid16": ("long", ()),
"geteuid": ("long", ()),
"geteuid16": ("long", ()),
"getgid": ("long", ()),
"getgid16": ("long", ()),
"getgroups": (
"long",
(("int", "gidsetsize"), ("gid_t *", "grouplist")),
),
"getgroups16": (
"long",
(("int", "gidsetsize"), ("old_gid_t *", "grouplist")),
),
"gethostname": ("long", (("char *", "name"), ("int", "len"))),
"getitimer": (
"long",
(("int", "which"), ("struct itimerval *", "value")),
),
"getpeername": (
"long",
(
("int", "sockfd"),
("struct sockaddr *", "addr"),
("int *", "addrlen"),
),
),
"getpgid": ("long", (("pid_t", "pid"),)),
"getpgrp": ("long", ()),
"getpid": ("long", ()),
"getppid": ("long", ()),
"getpriority": ("long", (("int", "which"), ("int", "who"))),
"getrandom": (
"long",
(
("void *", "buf"),
("size_t", "count"),
("unsigned int", "flags"),
),
),
"getresgid": (
"long",
(("gid_t *", "rgid"), ("gid_t *", "egid"), ("gid_t *", "sgid")),
),
"getresgid16": (
"long",
(
("old_gid_t *", "rgid"),
("old_gid_t *", "egid"),
("old_gid_t *", "sgid"),
),
),
"getresuid": (
"long",
(("uid_t *", "ruid"), ("uid_t *", "euid"), ("uid_t *", "suid")),
),
"getresuid16": (
"long",
(
("old_uid_t *", "ruid"),
("old_uid_t *", "euid"),
("old_uid_t *", "suid"),
),
),
"getrlimit": (
"long",
(("unsigned int", "resource"), ("struct rlimit *", "rlim")),
),
"ugetrlimit": (
"long",
(("unsigned int", "resource"), ("struct rlimit *", "rlim")),
),
"getrusage": ("long", (("int", "who"), ("struct rusage *", "ru"))),
"getsid": ("long", (("pid_t", "pid"),)),
"getsockname": (
"long",
(
("int", "sockfd"),
("struct sockaddr *", "addr"),
("int *", "addrlen"),
),
),
"getsockopt": (
"long",
(
("int", "fd"),
("int", "level"),
("int", "optname"),
("void *", "optval"),
("int *", "optlen"),
),
),
"gettid": ("long", ()),
"gettimeofday": (
"long",
(("struct timeval *", "tv"), ("struct timezone *", "tz")),
),
"getuid": ("long", ()),
"getuid16": ("long", ()),
"getuid32": ("long", ()),
"getxattr": (
"long",
(
("const char *", "path"),
("const char *", "name"),
("void *", "value"),
("size_t", "size"),
),
),
"init_module": (
"long",
(
("void *", "umod"),
("unsigned long", "len"),
("const char *", "uargs"),
),
),
"inotify_add_watch": (
"long",
(("int", "fd"), ("const char *", "path"), ("u32", "mask")),
),
"inotify_init": ("long", ()),
"inotify_init1": ("long", (("int", "flags"),)),
"inotify_rm_watch": ("long", (("int", "fd"), ("__s32", "wd"))),
"io_cancel": (
"long",
(
("aio_context_t", "ctx_id"),
("struct iocb *", "iocb"),
("struct io_event *", "result"),
),
),
"io_destroy": ("long", (("aio_context_t", "ctx"),)),
"io_getevents": (
"long",
(
("aio_context_t", "ctx_id"),
("long", "min_nr"),
("long", "nr"),
("struct io_event *", "events"),
("struct timespec *", "timeout"),
),
),
"io_getevents_time32": (
"long",
(
("__u32", "ctx_id"),
("__s32", "min_nr"),
("__s32", "nr"),
("struct io_event *", "events"),
("struct old_timespec32 *", "timeout"),
),
),
"io_pgetevents": (
"long",
(
("aio_context_t", "ctx_id"),
("long", "min_nr"),
("long", "nr"),
("struct io_event *", "events"),
("struct timespec *", "timeout"),
("const struct __aio_sigset *", "sig"),
),
),
"io_pgetevents_time32": (
"long",
(
("aio_context_t", "ctx_id"),
("long", "min_nr"),
("long", "nr"),
("struct io_event *", "events"),
("struct old_timespec32 *", "timeout"),
("const struct __aio_sigset *", "sig"),
),
),
"io_setup": (
"long",
(("unsigned", "nr_reqs"), ("aio_context_t *", "ctx")),
),
"io_submit": (
"long",
(
("aio_context_t", "ctx_id"),
("long", "nr"),
("struct iocb * *", "iocbpp"),
),
),
"io_uring_enter": (
"long",
(
("unsigned int", "fd"),
("u32", "to_submit"),
("u32", "min_complete"),
("u32", "flags"),
("const sigset_t *", "sig"),
("size_t", "sigsz"),
),
),
"io_uring_register": (
"long",
(
("unsigned int", "fd"),
("unsigned int", "op"),
("void *", "arg"),
("unsigned int", "nr_args"),
),
),
"io_uring_setup": (
"long",
(("u32", "entries"), ("struct io_uring_params *", "p")),
),
"ioctl": (
"long",
(
("unsigned int", "fd"),
("unsigned int", "cmd"),
("unsigned long", "arg"),
),
),
"ioperm": (
"long",
(
("unsigned long", "from"),
("unsigned long", "num"),
("int", "on"),
),
),
"iopl": (
"long",
(("int", "level")),
),
"ioprio_get": ("long", (("int", "which"), ("int", "who"))),
"ioprio_set": (
"long",
(("int", "which"), ("int", "who"), ("int", "ioprio")),
),
"ipc": (
"long",
(
("unsigned int", "call"),
("int", "first"),
("unsigned long", "second"),
("unsigned long", "third"),
("void *", "ptr"),
("long", "fifth"),
),
),
"kcmp": (
"long",
(
("pid_t", "pid1"),
("pid_t", "pid2"),
("int", "type"),
("unsigned long", "idx1"),
("unsigned long", "idx2"),
),
),
"kexec_file_load": (
"long",
(
("int", "kernel_fd"),
("int", "initrd_fd"),
("unsigned long", "cmdline_len"),
("const char *", "cmdline_ptr"),
("unsigned long", "flags"),
),
),
"kexec_load": (
"long",
(
("unsigned long", "entry"),
("unsigned long", "nr_segments"),
("struct kexec_segment *", "segments"),
("unsigned long", "flags"),
),
),
"keyctl": (
"long",
(
("int", "cmd"),
("unsigned long", "arg2"),
("unsigned long", "arg3"),
("unsigned long", "arg4"),
("unsigned long", "arg5"),
),
),
"kill": ("long", (("int", "pid"), ("int", "sig"))),
"lchown": (
"long",
(
("const char *", "filename"),
("uid_t", "user"),
("gid_t", "group"),
),
),
"lchown16": (
"long",
(
("const char *", "filename"),
("old_uid_t", "user"),
("old_gid_t", "group"),
),
),
"lgetxattr": (
"long",
(
("const char *", "path"),
("const char *", "name"),
("void *", "value"),
("size_t", "size"),
),
),
"link": (
"long",
(("const char *", "oldname"), ("const char *", "newname")),
),
"linkat": (
"long",
(
("int", "olddfd"),
("const char *", "oldname"),
("int", "newdfd"),
("const char *", "newname"),
("int", "flags"),
),
),
"listen": ("long", (("int", "sockfd"), ("int", "backlog"))),
"listxattr": (
"long",
(
("const char *", "path"),
("char char *", "list"),
("size_t", "size"),
),
),
"llistxattr": (
"long",
(
("const char *", "path"),
("char char *", "list"),
("size_t", "size"),
),
),
"llseek": (
"long",
(
("unsigned int", "fd"),
("unsigned long", "offset_high"),
("unsigned long", "offset_low"),
("loff_t *", "result"),
("unsigned int", "whence"),
),
),
"lookup_dcookie": (
"long",
(("u64", "cookie64"), ("char *", "buf"), ("size_t", "len")),
),
"lremovexattr": (
"long",
(("const char *", "path"), ("const char *", "name")),
),
"lseek": (
"long",
(
("unsigned int", "fd"),
("off_t", "offset"),
("unsigned int", "whence"),
),
),
"lsetxattr": (
"long",
(
("const char *", "path"),
("const char *", "name"),
("const void *", "value"),
("size_t", "size"),
("int", "flags"),
),
),
"lstat": (
"long",
(
("const char *", "filename"),
("struct __old_kernel_stat *", "statbuf"),
),
),
"lstat64": (
"long",
(("const char *", "filename"), ("struct stat64 *", "statbuf")),
),
"madvise": (
"long",
(
("unsigned long", "addr"),
("size_t", "length"),
("int", "advice"),
),
),
"mbind": (
"long",
(
("unsigned long", "start"),
("unsigned long", "len"),
("unsigned long", "mode"),
("const unsigned long *", "nmask"),
("unsigned long", "maxnode"),
("unsigned", "flags"),
),
),
"membarrier": ("long", (("int", "cmd"), ("int", "flags"))),
"memfd_create": (
"long",
(("const char *", "uname_ptr"), ("unsigned int", "flags")),
),
"migrate_pages": (
"long",
(
("pid_t", "pid"),
("unsigned long", "maxnode"),
("const unsigned long *", "from"),
("const unsigned long *", "to"),
),
),
"mincore": (
"long",
(
("unsigned long", "start"),
("size_t", "len"),
("unsigned char *", "vec"),
),
),
"mkdir": ("long", (("const char *", "pathname"), ("umode_t", "mode"))),
"mkdirat": (
"long",
(
("int", "dfd"),
("const char *", "pathname"),
("umode_t", "mode"),
),
),
"mknod": (
"long",
(
("const char *", "filename"),
("umode_t", "mode"),
("unsigned", "dev"),
),
),
"mknodat": (
"long",
(
("int", "dfd"),
("const char *", "filename"),
("umode_t", "mode"),
("unsigned", "dev"),
),
),
"mlock": ("long", (("unsigned long", "start"), ("size_t", "len"))),
"mlock2": (
"long",
(("unsigned long", "start"), ("size_t", "len"), ("int", "flags")),
),
"mlockall": ("long", (("int", "flags"),)),
"mmap_pgoff": (
"long",
(
("unsigned long", "addr"),
("unsigned long", "len"),
("unsigned long", "prot"),
("unsigned long", "flags"),
("unsigned long", "fd"),
("unsigned long", "pgoff"),
),
),
"mmap": (
"long",
(
("unsigned long", "addr"),
("unsigned long", "len"),
("unsigned long", "prot"),
("unsigned long", "flags"),
("unsigned long", "fd"),
("unsigned long", "pgoff"),
),
),
"mmap2": (
"long",
(
("unsigned long", "addr"),
("unsigned long", "len"),
("unsigned long", "prot"),
("unsigned long", "flags"),
("unsigned long", "fd"),
("unsigned long", "pgoff"),
),
),
"move_mount": (
"long",
(
("int", "from_dfd"),
("const char *", "from_path"),
("int", "to_dfd"),
("const char *", "to_path"),
("unsigned int", "ms_flags"),
),
),
"arch_prctl": ("int", (("int", "code"), ("unsigned long", "addr"))),
"mount": (
"long",
(
("const char *", "dev_name"),
("const char *", "dir_name"),
("const char *", "type"),
("unsigned long", "flags"),
("void *", "data"),
),
),
"move_pages": (
"long",
(
("pid_t", "pid"),
("unsigned long", "nr_pages"),
("const void * *", "pages"),
("const int *", "nodes"),
("int *", "status"),
("int", "flags"),
),
),
"mprotect": (
"long",
(
("unsigned long", "start"),
("size_t", "len"),
("unsigned long", "prot"),
),
),
"mq_getsetattr": (
"long",
(
("mqd_t", "mqdes"),
("const struct mq_attr *", "mqstat"),
("struct mq_attr *", "omqstat"),
),
),
"mq_notify": (
"long",
(("mqd_t", "mqdes"), ("const struct sigevent *", "notification")),
),
"mq_open": (
"long",
(
("const char *", "name"),
("int", "oflag"),
("umode_t", "mode"),
("struct mq_attr *", "attr"),
),
),
"mq_timedreceive": (
"long",
(
("mqd_t", "mqdes"),
("char *", "msg_ptr"),
("size_t", "msg_len"),
("unsigned int *", "msg_prio"),
("const struct timespec *", "abs_timeout"),
),
),
"mq_timedreceive_time32": (
"long",
(
("mqd_t", "mqdes"),
("char *", "u_msg_ptr"),
("unsigned int", "msg_len"),
("unsigned int *", "u_msg_prio"),
("const struct old_timespec32 *", "u_abs_timeout"),
),
),
"mq_timedsend": (
"long",
(
("mqd_t", "mqdes"),
("const char *", "msg_ptr"),
("size_t", "msg_len"),
("unsigned int", "msg_prio"),
("const struct timespec *", "abs_timeout"),
),
),
"mq_timedsend_time32": (
"long",
(
("mqd_t", "mqdes"),
("const char *", "u_msg_ptr"),
("unsigned int", "msg_len"),
("unsigned int", "msg_prio"),
("const struct old_timespec32 *", "u_abs_timeout"),
),
),
"mq_unlink": ("long", (("const char *", "name"),)),
"mremap": (
"long",
(
("unsigned long", "addr"),
("unsigned long", "old_len"),
("unsigned long", "new_len"),
("unsigned long", "flags"),
("unsigned long", "new_addr"),
),
),
"msgctl": (
"long",
(("int", "msqid"), ("int", "cmd"), ("struct msqid_ds *", "buf")),
),
"msgget": ("long", (("key_t", "key"), ("int", "msgflg"))),
"msgrcv": (
"long",
(
("int", "msqid"),
("struct msgbuf *", "msgp"),
("size_t", "msgsz"),
("long", "msgtyp"),
("int", "msgflg"),
),
),
"msgsnd": (
"long",
(
("int", "msqid"),
("struct msgbuf *", "msgp"),
("size_t", "msgsz"),
("int", "msgflg"),
),
),
"msync": (
"long",
(("unsigned long", "start"), ("size_t", "len"), ("int", "flags")),
),
"munlock": ("long", (("unsigned long", "start"), ("size_t", "len"))),
"munlockall": ("long", ()),
"munmap": ("long", (("unsigned long", "addr"), ("size_t", "len"))),
"name_to_handle_at": (
"long",
(
("int", "dfd"),
("const char *", "name"),
("struct file_handle *", "handle"),
("int *", "mnt_id"),
("int", "flag"),
),
),
"nanosleep": (
"long",
(("struct timespec *", "rqtp"), ("struct timespec *", "rmtp")),
),
"nanosleep_time32": (
"long",
(
("struct old_timespec32 *", "rqtp"),
("struct old_timespec32 *", "rmtp"),
),
),
"newfstat": (
"long",
(("unsigned int", "fd"), ("struct stat *", "statbuf")),
),
"newfstatat": (
"long",
(
("int", "dfd"),
("const char *", "filename"),
("struct stat *", "statbuf"),
("int", "flag"),
),
),
"newlstat": (
"long",
(("const char *", "filename"), ("struct stat *", "statbuf")),
),
"newstat": (
"long",
(("const char *", "filename"), ("struct stat *", "statbuf")),
),
"newuname": ("long", (("struct new_utsname *", "name"),)),
"ni_syscall": ("long", ()),
"nice": ("long", (("int", "increment"),)),
"old_getrlimit": (
"long",
(("unsigned int", "resource"), ("struct rlimit *", "rlim")),
),
"old_mmap": ("long", (("struct mmap_arg_struct *", "arg"),)),
"old_msgctl": (
"long",
(("int", "msqid"), ("int", "cmd"), ("struct msqid_ds *", "buf")),
),
"old_readdir": (
"long",
(
("unsigned int", "fd"),
("struct old_linux_dirent *", "dirp"),
("unsigned int", "count"),
),
),
"old_select": ("long", (("struct sel_arg_struct *", "arg"),)),
"old_semctl": (
"long",
(
("int", "semid"),
("int", "semnum"),
("int", "cmd"),
("unsigned long", "arg"),
),
),
"old_shmctl": (
"long",
(("int", "shmid"), ("int", "cmd"), ("struct shmid_ds *", "buf")),
),
"oldumount": ("long", (("char char *", "name"),)),
"olduname": ("long", (("struct oldold_utsname *", "buf"),)),
"open": (
"long",
(
("const char *", "filename"),
("int", "flags"),
("umode_t", "mode"),
),
),
"open_by_handle_at": (
"long",
(
("int", "mountdirfd"),
("struct file_handle *", "handle"),
("int", "flags"),
),
),
"open_tree": (
"long",
(("int", "dfd"), ("const char *", "path"), ("unsigned", "flags")),
),
"openat": (
"long",
(
("int", "dfd"),
("const char *", "filename"),
("int", "flags"),
("umode_t", "mode"),
),
),
"openat2": (
"long",
(
("int", "dfd"),
("const char *", "filename"),
("struct open_how *", "how"),
("size_t", "size"),
),
),
"pause": ("long", ()),
"pciconfig_iobase": (
"long",
(
("long", "which"),
("unsigned long", "bus"),
("unsigned long", "devfn"),
),
),
"pciconfig_read": (
"long",
(
("unsigned long", "bus"),
("unsigned long", "dfn"),
("unsigned long", "off"),
("unsigned long", "len"),
("void *", "buf"),
),
),
"pciconfig_write": (
"long",
(
("unsigned long", "bus"),
("unsigned long", "dfn"),
("unsigned long", "off"),
("unsigned long", "len"),
("void *", "buf"),
),
),
"perf_event_open": (
"long",
(
("struct perf_event_attr *", "attr_uptr"),
("pid_t", "pid"),
("int", "cpu"),
("int", "group_fd"),
("unsigned long", "flags"),
),
),
"personality": ("long", (("unsigned int", "personality"),)),
"pidfd_getfd": (
"long",
(("int", "pidfd"), ("int", "fd"), ("unsigned int", "flags")),
),
"pidfd_open": ("long", (("pid_t", "pid"), ("unsigned int", "flags"))),
"pidfd_send_signal": (
"long",
(
("int", "pidfd"),
("int", "sig"),
("siginfo_t *", "info"),
("unsigned int", "flags"),
),
),
"pipe": ("long", (("int *", "fildes"),)),
"pipe2": ("long", (("int *", "fildes"), ("int", "flags"))),
"pivot_root": (
"long",
(("const char *", "new_root"), ("const char *", "put_old")),
),
"pkey_alloc": (
"long",
(("unsigned long", "flags"), ("unsigned long", "init_val")),
),
"pkey_free": ("long", (("int", "pkey"),)),
"pkey_mprotect": (
"long",
(
("unsigned long", "start"),
("size_t", "len"),
("unsigned long", "prot"),
("int", "pkey"),
),
),
"poll": (
"long",
(
("struct pollfd *", "ufds"),
("unsigned int", "nfds"),
("int", "timeout"),
),
),
"ppoll": (
"long",
(
("struct pollfd *", "fds"),
("unsigned int", "nfds"),
("struct timespec *", "tmo_p"),
("const sigset_t *", "sigmask"),
),
),
"ppoll_time32": (
"long",
(
("struct pollfd *", "fds"),
("unsigned int", "nfds"),
("struct old_timespec *", "tmo_p"),
("const sigset_t *", "sigmask"),
),
),
"prctl": (
"long",
(
("int", "option"),
("unsigned long", "arg2"),
("unsigned long", "arg3"),
("unsigned long", "arg4"),
("unsigned long", "arg5"),
),
),
"pread64": (
"long",
(
("unsigned int", "fd"),
("void *", "buf"),
("size_t", "count"),
("loff_t", "pos"),
),
),
"preadv": (
"long",
(
("unsigned long", "fd"),
("const struct iovec *", "vec"),
("unsigned long", "vlen"),
("unsigned long", "pos_l"),
("unsigned long", "pos_h"),
),
),
"preadv2": (
"long",
(
("unsigned long", "fd"),
("const struct iovec *", "vec"),
("unsigned long", "vlen"),
("unsigned long", "pos_l"),
("unsigned long", "pos_h"),
("rwf_t", "flags"),
),
),
"prlimit64": (
"long",
(
("pid_t", "pid"),
("unsigned int", "resource"),
("const struct rlimit64 *", "new_rlim"),
("struct rlimit64 *", "old_rlim"),
),
),
"process_vm_readv": (
"long",
(
("pid_t", "pid"),
("const struct iovec *", "lvec"),
("unsigned long", "liovcnt"),
("const struct iovec *", "rvec"),
("unsigned long", "riovcnt"),
("unsigned long", "flags"),
),
),
"process_vm_writev": (
"long",
(
("pid_t", "pid"),
("const struct iovec *", "lvec"),
("unsigned long", "liovcnt"),
("const struct iovec *", "rvec"),
("unsigned long", "riovcnt"),
("unsigned long", "flags"),
),
),
"pselect6": (
"long",
(
("int", "nfds"),
("fd_set *", "readfds"),
("fd_set *", "writefds"),
("fd_set *", "exceptfds"),
("struct timespec *", "timeout"),
("void *", "sigmask"),
),
),
"pselect6_time32": (
"long",
(
("int", "nfds"),
("fd_set *", "readfds"),
("fd_set *", "writefds"),
("fd_set *", "exceptfds"),
("struct old_timespec32 *", ""),
("void *", "sigmask"),
),
),
"ptrace": (
"long",
(
("long", "request"),
("long", "pid"),
("unsigned long", "addr"),
("unsigned long", "data"),
),
),
"pwrite64": (
"long",
(
("unsigned int", "fd"),
("const char *", "buf"),
("size_t", "count"),
("loff_t", "pos"),
),
),
"pwritev": (
"long",
(
("unsigned long", "fd"),
("const struct iovec *", "vec"),
("unsigned long", "vlen"),
("unsigned long", "pos_l"),
("unsigned long", "pos_h"),
),
),
"pwritev2": (
"long",
(
("unsigned long", "fd"),
("const struct iovec *", "vec"),
("unsigned long", "vlen"),
("unsigned long", "pos_l"),
("unsigned long", "pos_h"),
("rwf_t", "flags"),
),
),
"quotactl": (
"long",
(
("unsigned int", "cmd"),
("const char *", "special"),
("qid_t", "id"),
("void *", "addr"),
),
),
"query_module": (
"long",
(
("const char *", "name"),
("int", "which"),
("void *", "buf"),
("int", "bufsize"),
("int *", "ret"),
),
),
"read": (
"long",
(("unsigned int", "fd"), ("void *", "buf"), ("size_t", "count")),
),
"readahead": (
"long",
(("int", "fd"), ("loff_t", "offset"), ("size_t", "count")),
),
"readlink": (
"long",
(("const char *", "path"), ("char *", "buf"), ("int", "bufsiz")),
),
"readlinkat": (
"long",
(
("int", "dfd"),
("const char *", "path"),
("char *", "buf"),
("int", "bufsiz"),
),
),
"readv": (
"long",
(
("unsigned long", "fd"),
("const struct iovec *", "vec"),
("unsigned long", "vlen"),
),
),
"reboot": (
"long",
(
("int", "magic1"),
("int", "magic2"),
("unsigned int", "cmd"),
("void *", "arg"),
),
),
"recv": (
"long",
(
("int", "sockfd"),
("void *", "buf"),
("size_t", "len"),
("unsigned", "flags"),
),
),
"recvfrom": (
"long",
(
("int", "sockfd"),
("void *", "buf"),
("size_t", "len"),
("unsigned", "flags"),
("struct sockaddr *", "src_addr"),
("int *", "addrlen"),
),
),
"recvmmsg": (
"long",
(
("int", "fd"),
("struct mmsghdr *", "msg"),
("unsigned int", "vlen"),
("unsigned", "flags"),
("struct timespec *", "timeout"),
),
),
"recvmmsg_time32": (
"long",
(
("int", "fd"),
("struct mmsghdr *", "msg"),
("unsigned int", "vlen"),
("unsigned", "flags"),
("struct old_timespec32 *", "timeout"),
),
),
"recvmsg": (
"long",
(
("int", "fd"),
("struct user_msghdr *", "msg"),
("unsigned", "flags"),
),
),
"remap_file_pages": (
"long",
(
("unsigned long", "start"),
("unsigned long", "size"),
("unsigned long", "prot"),
("unsigned long", "pgoff"),
("unsigned long", "flags"),
),
),
"removexattr": (
"long",
(("const char *", "path"), ("const char *", "name")),
),
"rename": (
"long",
(("const char *", "oldname"), ("const char *", "newname")),
),
"renameat": (
"long",
(
("int", "olddfd"),
("const char *", "oldname"),
("int", "newdfd"),
("const char *", "newname"),
),
),
"renameat2": (
"long",
(
("int", "olddfd"),
("const char *", "oldname"),
("int", "newdfd"),
("const char *", "newname"),
("unsigned int", "flags"),
),
),
"request_key": (
"long",
(
("const char *", "_type"),
("const char *", "_description"),
("const char *", "_callout_info"),
("key_serial_t", "destringid"),
),
),
"restart_syscall": ("long", ()),
"rmdir": ("long", (("const char *", "pathname"),)),
"rseq": (
"long",
(
("struct rseq *", "rseq"),
("uint32_t", "rseq_len"),
("int", "flags"),
("uint32_t", "sig"),
),
),
"rt_sigaction": (
"long",
(
("int", "signum"),
("const struct sigaction *", "act"),
("struct sigaction *", "oldact"),
("size_t", ""),
),
),
"rt_sigpending": (
"long",
(("sigset_t *", "set"), ("size_t", "sigsetsize")),
),
"rt_sigreturn": ("long", ()),
"rt_sigprocmask": (
"long",
(
("int", "how"),
("sigset_t *", "set"),
("sigset_t *", "oset"),
("size_t", "sigsetsize"),
),
),
"rt_sigqueueinfo": (
"long",
(("int", "pid"), ("int", "sig"), ("siginfo_t *", "uinfo")),
),
"rt_sigsuspend": (
"long",
(("sigset_t *", "unewset"), ("size_t", "sigsetsize")),
),
"rt_sigtimedwait": (
"long",
(
("const sigset_t *", "uthese"),
("siginfo_t *", "uinfo"),
("const struct timespec *", "uts"),
("size_t", "sigsetsize"),
),
),
"rt_sigtimedwait_time32": (
"long",
(
("const sigset_t *", "uthese"),
("siginfo_t *", "uinfo"),
("const struct old_timespec32 *", "uts"),
("size_t", "sigsetsize"),
),
),
"rt_tgsigqueueinfo": (
"long",
(
("pid_t", "tgid"),
("pid_t", "pid"),
("int", "sig"),
("siginfo_t *", "uinfo"),
),
),
"sched_get_priority_max": ("long", (("int", "policy"),)),
"sched_get_priority_min": ("long", (("int", "policy"),)),
"sched_getaffinity": (
"long",
(
("pid_t", "pid"),
("unsigned int", "len"),
("unsigned long *", "user_mask_ptr"),
),
),
"sched_getattr": (
"long",
(
("pid_t", "pid"),
("struct sched_attr *", "attr"),
("unsigned int", "size"),
("unsigned int", "flags"),
),
),
"sched_getparam": (
"long",
(("pid_t", "pid"), ("struct sched_param *", "param")),
),
"sched_getscheduler": ("long", (("pid_t", "pid"),)),
"sched_rr_get_interval": (
"long",
(("pid_t", "pid"), ("struct timespec *", "interval")),
),
"sched_rr_get_interval_time32": (
"long",
(("pid_t", "pid"), ("struct old_timespec32 *", "interval")),
),
"sched_setaffinity": (
"long",
(
("pid_t", "pid"),
("unsigned int", "len"),
("unsigned long *", "user_mask_ptr"),
),
),
"sched_setattr": (
"long",
(
("pid_t", "pid"),
("struct sched_attr *", "attr"),
("unsigned int", "flags"),
),
),
"sched_setparam": (
"long",
(("pid_t", "pid"), ("struct sched_param *", "param")),
),
"sched_setscheduler": (
"long",
(
("pid_t", "pid"),
("int", "policy"),
("struct sched_param *", "param"),
),
),
"sched_yield": ("long", ()),
"seccomp": (
"long",
(
("unsigned int", "op"),
("unsigned int", "flags"),
("const char *", "uargs"),
),
),
"select": (
"long",
(
("int", "n"),
("fd_set *", "inp"),
("fd_set *", "outp"),
("fd_set *", "exp"),
("struct timeval *", "tvp"),
),
),
"newselect": (
"long",
(
("int", "n"),
("fd_set *", "inp"),
("fd_set *", "outp"),
("fd_set *", "exp"),
("struct timeval *", "tvp"),
),
),
"semctl": (
"long",
(
("int", "semid"),
("int", "semnum"),
("int", "cmd"),
("unsigned long", "arg"),
),
),
"semget": (
"long",
(("key_t", "key"), ("int", "nsems"), ("int", "semflg")),
),
"semop": (
"long",
(
("int", "semid"),
("struct sembuf *", "sops"),
("unsigned", "nsops"),
),
),
"semtimedop": (
"long",
(
("int", "semid"),
("struct sembuf *", "sops"),
("unsigned", "nsops"),
("const struct timespec *", "timeout"),
),
),
"semtimedop_time32": (
"long",
(
("int", "semid"),
("struct sembuf *", "sops"),
("unsigned", "nsops"),
("const struct old_timespec32 *", "timeout"),
),
),
"send": (
"long",
(
("int", "sockfd"),
("void *", "buf"),
("size_t", "len"),
("unsigned", "flags"),
),
),
"sendfile": (
"long",
(
("int", "out_fd"),
("int", "in_fd"),
("off_t *", "offset"),
("size_t", "count"),
),
),
"sendfile64": (
"long",
(
("int", "out_fd"),
("int", "in_fd"),
("loff_t *", "offset"),
("size_t", "count"),
),
),
"sendmmsg": (
"long",
(
("int", "fd"),
("struct mmsghdr *", "msg"),
("unsigned int", "vlen"),
("unsigned", "flags"),
),
),
"sendmsg": (
"long",
(
("int", "fd"),
("struct user_msghdr *", "msg"),
("unsigned", "flags"),
),
),
"sendto": (
"long",
(
("int", "sockfd"),
("void *", "buf"),
("size_t", "len"),
("unsigned", "flags"),
("struct sockaddr *", "destAddr"),
("int", "addrlen"),
),
),
"set_mempolicy": (
"long",
(
("int", "mode"),
("const unsigned long *", "nmask"),
("unsigned long", "maxnode"),
),
),
"set_robust_list": (
"long",
(("struct robust_list_head *", "head"), ("size_t", "len")),
),
"set_tid_address": ("long", (("int *", "tidptr"),)),
"setdomainname": ("long", (("const char *", "name"), ("int", "len"))),
"setfsgid": ("long", (("gid_t", "gid"),)),
"setfsgid16": ("long", (("old_gid_t", "gid"),)),
"setfsuid": ("long", (("uid_t", "uid"),)),
"setfsuid16": ("long", (("old_uid_t", "uid"),)),
"setgid": ("long", (("gid_t", "gid"),)),
"setgid16": ("long", (("old_gid_t", "gid"),)),
"setgroups": (
"long",
(("int", "gidsetsize"), ("gid_t *", "grouplist")),
),
"setgroups16": (
"long",
(("int", "gidsetsize"), ("old_gid_t *", "grouplist")),
),
"sethostname": ("long", (("const char *", "name"), ("int", "len"))),
"setitimer": (
"long",
(
("int", "which"),
("struct itimerval *", "value"),
("struct itimerval *", "ovalue"),
),
),
"setns": ("long", (("int", "fd"), ("int", "nstype"))),
"setpgid": ("long", (("pid_t", "pid"), ("pid_t", "pgid"))),
"setpriority": (
"long",
(("int", "which"), ("int", "who"), ("int", "niceval")),
),
"setregid": ("long", (("gid_t", "rgid"), ("gid_t", "egid"))),
"setregid16": ("long", (("old_gid_t", "rgid"), ("old_gid_t", "egid"))),
"setresgid": (
"long",
(("gid_t", "rgid"), ("gid_t", "egid"), ("gid_t", "sgid")),
),
"setresgid16": (
"long",
(
("old_gid_t", "rgid"),
("old_gid_t", "egid"),
("old_gid_t", "sgid"),
),
),
"setresuid": (
"long",
(("uid_t", "ruid"), ("uid_t", "euid"), ("uid_t", "suid")),
),
"setresuid16": (
"long",
(
("old_uid_t", "ruid"),
("old_uid_t", "euid"),
("old_uid_t", "suid"),
),
),
"setreuid": ("long", (("uid_t", "ruid"), ("uid_t", "euid"))),
"setreuid16": ("long", (("old_uid_t", "ruid"), ("old_uid_t", "euid"))),
"setrlimit": (
"long",
(("unsigned int", "resource"), ("struct rlimit *", "rlim")),
),
"setsid": ("long", ()),
"setsockopt": (
"long",
(
("int", "fd"),
("int", "level"),
("int", "optname"),
("const void *", "optval"),
("int", "optlen"),
),
),
"settimeofday": (
"long",
(("struct timeval *", "tv"), ("struct timezone *", "tz")),
),
"setuid": ("long", (("uid_t", "uid"),)),
"setuid16": ("long", (("old_uid_t", "uid"),)),
"setxattr": (
"long",
(
("const char *", "path"),
("const char *", "name"),
("const void *", "value"),
("size_t", "size"),
("int", "flags"),
),
),
"sgetmask": ("long", ()),
"shmat": (
"long",
(("int", "shmid"), ("const void *", "shmaddr"), ("int", "shmflg")),
),
"shmctl": (
"long",
(("int", "shmid"), ("int", "cmd"), ("struct shmid_ds *", "buf")),
),
"shmdt": ("long", (("const void *", "shmaddr"),)),
"shmget": (
"long",
(("key_t", "key"), ("size_t", "size"), ("int", "flag")),
),
"shutdown": ("long", (("int", "sockfd"), ("int", "how"))),
"sigaction": (
"long",
(
("int", "signum"),
("const struct old_sigaction *", "act"),
("struct old_sigaction *", "oldact"),
),
),
"sigaltstack": (
"long",
(
("const struct sigaltstack *", "uss"),
("struct sigaltstack *", "uoss"),
),
),
"signal": ("long", (("int", "sig"), ("__sighandler_t", "handler"))),
"signalfd": (
"long",
(
("int", "ufd"),
("sigset_t *", "user_mask"),
("size_t", "sizemask"),
),
),
"signalfd4": (
"long",
(
("int", "ufd"),
("sigset_t *", "user_mask"),
("size_t", "sizemask"),
("int", "flags"),
),
),
"sigpending": ("long", (("old_sigset_t *", "set"),)),
"sigprocmask": (
"long",
(
("int", "how"),
("old_sigset_t *", "set"),
("old_sigset_t *", "oset"),
),
),
"sigsuspend": (
"long",
(("int", "unused1"), ("int", "unused2"), ("old_sigset_t", "mask")),
),
"socket": (
"long",
(("int", "domain"), ("int", "type"), ("int", "protocol")),
),
"socketcall": ("long", (("int", "call"), ("unsigned long *", "args"))),
"socketpair": (
"long",
(
("int", "domain"),
("int", "type"),
("int", "protocol"),
("int *", "sv"),
),
),
"splice": (
"long",
(
("int", "fd_in"),
("loff_t *", "off_in"),
("int", "fd_out"),
("loff_t *", "off_out"),
("size_t", "len"),
("unsigned int", "flags"),
),
),
"spu_create": (
"long",
(
("const char *", "name"),
("unsigned int", "flags"),
("umode_t", "mode"),
("int", "fd"),
),
),
"spu_run": (
"long",
(("int", "fd"), ("__u32 *", "unpc"), ("__u32 *", "ustatus")),
),
"ssetmask": ("long", (("int", "newmask"),)),
"stat": (
"long",
(
("const char *", "filename"),
("struct __old_kernel_stat *", "statbuf"),
),
),
"stat64": (
"long",
(("const char *", "filename"), ("struct stat64 *", "statbuf")),
),
"statfs": (
"long",
(("const char *", "path"), ("struct statfs *", "buf")),
),
"statfs64": (
"long",
(
("const char *", "path"),
("size_t", "sz"),
("struct statfs64 *", "buf"),
),
),
"statx": (
"long",
(
("int", "dfd"),
("const char *", "path"),
("unsigned", "flags"),
("unsigned", "mask"),
("struct statx *", "statxbuf"),
),
),
"stime": ("long", (("old_time_t *", "tptr"),)),
"stime32": ("long", (("old_time32_t *", "tptr"),)),
"swapoff": ("long", (("const char *", "specialfile"),)),
"swapon": (
"long",
(("const char *", "specialfile"), ("int", "swap_flags")),
),
"symlink": (
"long",
(("const char *", "old"), ("const char *", "new")),
),
"symlinkat": (
"long",
(
("const char *", "oldname"),
("int", "newdfd"),
("const char *", "newname"),
),
),
"sync": ("long", ()),
"sync_file_range": (
"long",
(
("int", "fd"),
("loff_t", "offset"),
("loff_t", "nbytes"),
("unsigned int", "flags"),
),
),
"sync_file_range2": (
"long",
(
("int", "fd"),
("unsigned int", "flags"),
("loff_t", "offset"),
("loff_t", "nbytes"),
),
),
"syncfs": ("long", (("int", "fd"),)),
"sysctl": ("long", (("struct __sysctl_args *", "args"),)),
"sysfs": (
"long",
(
("int", "option"),
("unsigned long", "arg1"),
("unsigned long", "arg2"),
),
),
"sysinfo": ("long", (("struct sysinfo *", "info"),)),
"syslog": (
"long",
(("int", "type"), ("char *", "buf"), ("int", "len")),
),
"tee": (
"long",
(
("int", "fdin"),
("int", "fdout"),
("size_t", "len"),
("unsigned int", "flags"),
),
),
"tgkill": ("long", (("int", "tgid"), ("int", "pid"), ("int", "sig"))),
"time": ("long", (("old_time_t *", "tloc"),)),
"time32": ("long", (("old_time32_t *", "tloc"),)),
"timer_create": (
"long",
(
("clockid_t", "which_clock"),
("struct sigevent *", "timer_event_spec"),
("timer_t *", "created_timer_id"),
),
),
"timer_delete": ("long", (("timer_t", "timer_id"),)),
"timer_getoverrun": ("long", (("timer_t", "timer_id"),)),
"timer_gettime": (
"long",
(("timer_t", "timer_id"), ("struct itimerspec *", "setting")),
),
"timer_gettime32": (
"long",
(
("timer_t", "timer_id"),
("struct old_itimerspec32 *", "setting"),
),
),
"timer_settime": (
"long",
(
("timer_t", "timer_id"),
("int", "flags"),
("const struct itimerspec *", "new_setting"),
("struct itimerspec *", "old_setting"),
),
),
"timer_settime32": (
"long",
(
("timer_t", "timer_id"),
("int", "flags"),
("struct old_itimerspec32 *", "new"),
("struct old_itimerspec32 *", "old"),
),
),
"timerfd_create": ("long", (("int", "clockid"), ("int", "flags"))),
"timerfd_gettime": (
"long",
(("int", "ufd"), ("struct itimerspec *", "otmr")),
),
"timerfd_gettime32": (
"long",
(("int", "ufd"), ("struct old_itimerspec32 *", "otmr")),
),
"timerfd_settime": (
"long",
(
("int", "ufd"),
("int", "flags"),
("const struct itimerspec *", "utmr"),
("struct itimerspec *", "otmr"),
),
),
"timerfd_settime32": (
"long",
(
("int", "ufd"),
("int", "flags"),
("const struct old_itimerspec32 *", "utmr"),
("struct old_itimerspec32 *", "otmr"),
),
),
"times": ("long", (("struct tms *", "tbuf"),)),
"tkill": ("long", (("int", "pid"), ("int", "sig"))),
"truncate": ("long", (("const char *", "path"), ("long", "length"))),
"truncate64": (
"long",
(("const char *", "path"), ("loff_t", "length")),
),
"umask": ("long", (("int", "mask"),)),
"umount": ("long", (("const char *", "name"), ("int", "flags"))),
"umount2": ("long", (("const char *", "name"), ("int", "flags"))),
"uname": ("long", (("struct old_utsname *", "buf"),)),
"unlink": ("long", (("const char *", "pathname"),)),
"unlinkat": (
"long",
(("int", "dfd"), ("const char *", "pathname"), ("int", "flag")),
),
"unshare": ("long", (("unsigned long", "unshare_flags"),)),
"uselib": ("long", (("const char *", "library"),)),
"userfaultfd": ("long", (("int", "flags"),)),
"ustat": ("long", (("unsigned", "dev"), ("struct ustat *", "ubuf"))),
"utime": (
"long",
(("const char *", "filename"), ("struct utimbuf *", "times")),
),
"utime32": (
"long",
(("const char *", "filename"), ("struct old_utimbuf32 *", "t")),
),
"utimensat": (
"long",
(
("int", "dfd"),
("const char *", "filename"),
("struct timespec *", "utimes"),
("int", "flags"),
),
),
"utimensat_time32": (
"long",
(
("unsigned int", "dfd"),
("const char *", "filename"),
("struct old_timespec32 *", "t"),
("int", "flags"),
),
),
"utimes": (
"long",
(("const char *", "filename"), ("struct old_timeval *", "utimes")),
),
"utimes_time32": (
"long",
(("const char *", "filename"), ("struct old_timeval32 *", "t")),
),
"vfork": ("long", ()),
"vhangup": ("long", ()),
"vmsplice": (
"long",
(
("int", "fd"),
("const struct iovec *", "iov"),
("unsigned long", "nr_segs"),
("unsigned int", "flags"),
),
),
"wait4": (
"long",
(
("pid_t", "pid"),
("int *", "stat_addr"),
("int", "options"),
("struct rusage *", "ru"),
),
),
"waitid": (
"long",
(
("int", "which"),
("pid_t", "pid"),
("struct siginfo *", "infop"),
("int", "options"),
("struct rusage *", "ru"),
),
),
"waitpid": (
"long",
(("pid_t", "pid"), ("int *", "stat_addr"), ("int", "options")),
),
"write": (
"long",
(
("unsigned int", "fd"),
("const char *", "buf"),
("size_t", "count"),
),
),
"writev": (
"long",
(
("unsigned long", "fd"),
("const struct iovec *", "vec"),
("unsigned long", "vlen"),
),
),
}
"""
update syscalls from https://github.com/strace/src/linux/ARCH/syscallent.h
1. %s/\[.*= //g
2. %s/{.*),\s*"/\'sys_/g
3. %s/".*,/\',/g
4. paste the processed list
4. call UtilMgr.printSyscalls(ConfigMgr.SYSCALL_X86)
"""
# common 32bit syscalls from 403 ~ 423 #
SYSCALL_COMMON32 = [
"sys_clock_gettime64",
"sys_clock_settime64",
"sys_clock_adjtime64",
"sys_clock_getres_time64",
"sys_clock_nanosleep_time64",
"sys_timer_gettime64",
"sys_timer_settime64",
"sys_timerfd_gettime64",
"sys_timerfd_settime64",
"sys_utimensat_time64",
"sys_pselect6_time64",
"sys_ppoll_time64",
"sys_unused",
"sys_io_pgetevents_time64",
"sys_recvmmsg_time64",
"sys_mq_timedsend_time64",
"sys_mq_timedreceive_time64",
"sys_semtimedop_time64",
"sys_rt_sigtimedwait_time64",
"sys_futex_time64",
"sys_sched_rr_get_interval_time64",
]
# common syscalls from 424 ~ 447 #
SYSCALL_COMMON = [
"sys_pidfd_send_signal",
"sys_io_uring_setup",
"sys_io_uring_enter",
"sys_io_uring_register",
"sys_open_tree",
"sys_move_mount",
"sys_fsopen",
"sys_fsconfig",
"sys_fsmount",
"sys_fspick",
"sys_pidfd_open",
"sys_clone3",
"sys_close_range",
"sys_openat2",
"sys_pidfd_getfd",
"sys_faccessat2",
"sys_process_madvise",
"sys_epoll_pwait2",
"sys_mount_setattr",
"sys_quotactl_fd",
"sys_landlock_create_ruleset",
"sys_landlock_add_rule",
"sys_landlock_restrict_self",
"sys_memfd_secret",
]
# syscall for ARM #
SYSCALL_ARM = (
[
"sys_restart_syscall",
"sys_exit",
"sys_fork",
"sys_read",
"sys_write",
"sys_open",
"sys_close",
"sys_waitpid",
"sys_creat",
"sys_link",
"sys_unlink",
"sys_execve",
"sys_chdir",
"sys_time",
"sys_mknod",
"sys_chmod",
"sys_lchown",
"sys_break",
"sys_oldstat",
"sys_lseek",
"sys_getpid",
"sys_mount",
"sys_umount",
"sys_setuid",
"sys_getuid",
"sys_stime",
"sys_ptrace",
"sys_alarm",
"sys_oldfstat",
"sys_pause",
"sys_utime",
"sys_stty",
"sys_gtty",
"sys_access",
"sys_nice",
"sys_ftime",
"sys_sync",
"sys_kill",
"sys_rename",
"sys_mkdir",
"sys_rmdir",
"sys_dup",
"sys_pipe",
"sys_times",
"sys_prof",
"sys_brk",
"sys_setgid",
"sys_getgid",
"sys_signal",
"sys_geteuid",
"sys_getegid",
"sys_acct",
"sys_umount2",
"sys_lock",
"sys_ioctl",
"sys_fcntl",
"sys_mpx",
"sys_setpgid",
"sys_ulimit",
"sys_oldolduname",
"sys_umask",
"sys_chroot",
"sys_ustat",
"sys_dup2",
"sys_getppid",
"sys_getpgrp",
"sys_setsid",
"sys_sigaction",
"sys_sgetmask",
"sys_ssetmask",
"sys_setreuid",
"sys_setregid",
"sys_sigsuspend",
"sys_sigpending",
"sys_sethostname",
"sys_setrlimit",
"sys_getrlimit",
"sys_getrusage",
"sys_gettimeofday",
"sys_settimeofday",
"sys_getgroups",
"sys_setgroups",
"sys_select",
"sys_symlink",
"sys_oldlstat",
"sys_readlink",
"sys_uselib",
"sys_swapon",
"sys_reboot",
"sys_readdir",
"sys_mmap",
"sys_munmap",
"sys_truncate",
"sys_ftruncate",
"sys_fchmod",
"sys_fchown",
"sys_getpriority",
"sys_setpriority",
"sys_profil",
"sys_statfs",
"sys_fstatfs",
"sys_ioperm",
"sys_socketcall",
"sys_syslog",
"sys_setitimer",
"sys_getitimer",
"sys_stat",
"sys_lstat",
"sys_fstat",
"sys_olduname",
"sys_iopl",
"sys_vhangup",
"sys_idle",
"sys_syscall",
"sys_wait4",
"sys_swapoff",
"sys_sysinfo",
"sys_ipc",
"sys_fsync",
"sys_sigreturn",
"sys_clone",
"sys_setdomainname",
"sys_uname",
"sys_modify_ldt",
"sys_adjtimex",
"sys_mprotect",
"sys_sigprocmask",
"sys_create_module",
"sys_init_module",
"sys_delete_module",
"sys_get_kernel_syms",
"sys_quotactl",
"sys_getpgid",
"sys_fchdir",
"sys_bdflush",
"sys_sysfs",
"sys_personality",
"sys_afs_syscall",
"sys_setfsuid",
"sys_setfsgid",
"sys_llseek",
"sys_getdents",
"sys_newselect",
"sys_flock",
"sys_msync",
"sys_readv",
"sys_writev",
"sys_getsid",
"sys_fdatasync",
"sys_sysctl",
"sys_mlock",
"sys_munlock",
"sys_mlockall",
"sys_munlockall",
"sys_sched_setparam",
"sys_sched_getparam",
"sys_sched_setscheduler",
"sys_sched_getscheduler",
"sys_sched_yield",
"sys_sched_get_priority_max",
"sys_sched_get_priority_min",
"sys_sched_rr_get_interval",
"sys_nanosleep",
"sys_mremap",
"sys_setresuid",
"sys_getresuid",
"sys_vm86",
"sys_query_module",
"sys_poll",
"sys_nfsservctl",
"sys_setresgid",
"sys_getresgid",
"sys_prctl",
"sys_rt_sigreturn",
"sys_rt_sigaction",
"sys_rt_sigprocmask",
"sys_rt_sigpending",
"sys_rt_sigtimedwait",
"sys_rt_sigqueueinfo",
"sys_rt_sigsuspend",
"sys_pread64",
"sys_pwrite64",
"sys_chown",
"sys_getcwd",
"sys_capget",
"sys_capset",
"sys_sigaltstack",
"sys_sendfile",
"sys_getpmsg",
"sys_putpmsg",
"sys_vfork",
"sys_ugetrlimit",
"sys_mmap2",
"sys_truncate64",
"sys_ftruncate64",
"sys_stat64",
"sys_lstat64",
"sys_fstat64",
"sys_lchown32",
"sys_getuid32",
"sys_getgid32",
"sys_geteuid32",
"sys_getegid32",
"sys_setreuid32",
"sys_setregid32",
"sys_getgroups32",
"sys_setgroups32",
"sys_fchown32",
"sys_setresuid32",
"sys_getresuid32",
"sys_setresgid32",
"sys_getresgid32",
"sys_chown32",
"sys_setuid32",
"sys_setgid32",
"sys_setfsuid32",
"sys_setfsgid32",
"sys_getdents64",
"sys_pivot_root",
"sys_mincore",
"sys_madvise",
"sys_fcntl64",
"sys_tux",
"sys_unused",
"sys_gettid",
"sys_readahead",
"sys_setxattr",
"sys_lsetxattr",
"sys_fsetxattr",
"sys_getxattr",
"sys_lgetxattr",
"sys_fgetxattr",
"sys_listxattr",
"sys_llistxattr",
"sys_flistxattr",
"sys_removexattr",
"sys_lremovexattr",
"sys_fremovexattr",
"sys_tkill",
"sys_sendfile64",
"sys_futex",
"sys_sched_setaffinity",
"sys_sched_getaffinity",
"sys_io_setup",
"sys_io_destroy",
"sys_io_getevents",
"sys_io_submit",
"sys_io_cancel",
"sys_exit_group",
"sys_lookup_dcookie",
"sys_epoll_create",
"sys_epoll_ctl",
"sys_epoll_wait",
"sys_remap_file_pages",
"sys_set_thread_area",
"sys_get_thread_area",
"sys_set_tid_address",
"sys_timer_create",
"sys_timer_settime",
"sys_timer_gettime",
"sys_timer_getoverrun",
"sys_timer_delete",
"sys_clock_settime",
"sys_clock_gettime",
"sys_clock_getres",
"sys_clock_nanosleep",
"sys_statfs64",
"sys_fstatfs64",
"sys_tgkill",
"sys_utimes",
"sys_fadvise64_64",
"sys_pciconfig_iobase",
"sys_pciconfig_read",
"sys_pciconfig_write",
"sys_mq_open",
"sys_mq_unlink",
"sys_mq_timedsend",
"sys_mq_timedreceive",
"sys_mq_notify",
"sys_mq_getsetattr",
"sys_waitid",
"sys_socket",
"sys_bind",
"sys_connect",
"sys_listen",
"sys_accept",
"sys_getsockname",
"sys_getpeername",
"sys_socketpair",
"sys_send",
"sys_sendto",
"sys_recv",
"sys_recvfrom",
"sys_shutdown",
"sys_setsockopt",
"sys_getsockopt",
"sys_sendmsg",
"sys_recvmsg",
"sys_semop",
"sys_semget",
"sys_semctl",
"sys_msgsnd",
"sys_msgrcv",
"sys_msgget",
"sys_msgctl",
"sys_shmat",
"sys_shmdt",
"sys_shmget",
"sys_shmctl",
"sys_add_key",
"sys_request_key",
"sys_keyctl",
"sys_semtimedop",
"sys_vserver",
"sys_ioprio_set",
"sys_ioprio_get",
"sys_inotify_init",
"sys_inotify_add_watch",
"sys_inotify_rm_watch",
"sys_mbind",
"sys_get_mempolicy",
"sys_set_mempolicy",
"sys_openat",
"sys_mkdirat",
"sys_mknodat",
"sys_fchownat",
"sys_futimesat",
"sys_fstatat64",
"sys_unlinkat",
"sys_renameat",
"sys_linkat",
"sys_symlinkat",
"sys_readlinkat",
"sys_fchmodat",
"sys_faccessat",
"sys_pselect6",
"sys_ppoll",
"sys_unshare",
"sys_set_robust_list",
"sys_get_robust_list",
"sys_splice",
"sys_sync_file_range2",
"sys_tee",
"sys_vmsplice",
"sys_move_pages",
"sys_getcpu",
"sys_epoll_pwait",
"sys_kexec_load",
"sys_utimensat",
"sys_signalfd",
"sys_timerfd_create",
"sys_eventfd",
"sys_fallocate",
"sys_timerfd_settime",
"sys_timerfd_gettime",
"sys_signalfd4",
"sys_eventfd2",
"sys_epoll_create1",
"sys_dup3",
"sys_pipe2",
"sys_inotify_init1",
"sys_preadv",
"sys_pwritev",
"sys_rt_tgsigqueueinfo",
"sys_perf_event_open",
"sys_recvmmsg",
"sys_accept4",
"sys_fanotify_init",
"sys_fanotify_mark",
"sys_prlimit64",
"sys_name_to_handle_at",
"sys_open_by_handle_at",
"sys_clock_adjtime",
"sys_syncfs",
"sys_sendmmsg",
"sys_setns",
"sys_process_vm_readv",
"sys_process_vm_writev",
"sys_kcmp",
"sys_finit_module",
"sys_sched_setattr",
"sys_sched_getattr",
"sys_renameat2",
"sys_seccomp",
"sys_getrandom",
"sys_memfd_create",
"sys_bpf",
"sys_execveat",
"sys_userfaultfd",
"sys_membarrier",
"sys_mlock2",
"sys_copy_file_range",
"sys_preadv2",
"sys_pwritev2",
"sys_pkey_mprotect",
"sys_pkey_alloc",
"sys_pkey_free",
"sys_statx",
"sys_rseq",
"sys_io_pgetevents",
"sys_migrate_pages",
"sys_kexec_file_load",
"sys_unused",
]
+ SYSCALL_COMMON32
+ SYSCALL_COMMON
)
# syscall for AARCH64 #
SYSCALL_AARCH64 = (
[
"sys_io_setup",
"sys_io_destroy",
"sys_io_submit",
"sys_io_cancel",
"sys_io_getevents",
"sys_setxattr",
"sys_lsetxattr",
"sys_fsetxattr",
"sys_getxattr",
"sys_lgetxattr",
"sys_fgetxattr",
"sys_listxattr",
"sys_llistxattr",
"sys_flistxattr",
"sys_removexattr",
"sys_lremovexattr",
"sys_fremovexattr",
"sys_getcwd",
"sys_lookup_dcookie",
"sys_eventfd2",
"sys_epoll_create1",
"sys_epoll_ctl",
"sys_epoll_pwait",
"sys_dup",
"sys_dup3",
"sys_fcntl",
"sys_inotify_init1",
"sys_inotify_add_watch",
"sys_inotify_rm_watch",
"sys_ioctl",
"sys_ioprio_set",
"sys_ioprio_get",
"sys_flock",
"sys_mknodat",
"sys_mkdirat",
"sys_unlinkat",
"sys_symlinkat",
"sys_linkat",
"sys_renameat",
"sys_umount2",
"sys_mount",
"sys_pivot_root",
"sys_nfsservctl",
"sys_statfs",
"sys_fstatfs",
"sys_truncate",
"sys_ftruncate",
"sys_fallocate",
"sys_faccessat",
"sys_chdir",
"sys_fchdir",
"sys_chroot",
"sys_fchmod",
"sys_fchmodat",
"sys_fchownat",
"sys_fchown",
"sys_openat",
"sys_close",
"sys_vhangup",
"sys_pipe2",
"sys_quotactl",
"sys_getdents64",
"sys_lseek",
"sys_read",
"sys_write",
"sys_readv",
"sys_writev",
"sys_pread64",
"sys_pwrite64",
"sys_preadv",
"sys_pwritev",
"sys_sendfile",
"sys_pselect6",
"sys_ppoll",
"sys_signalfd4",
"sys_vmsplice",
"sys_splice",
"sys_tee",
"sys_readlinkat",
"sys_newfstatat",
"sys_fstat",
"sys_sync",
"sys_fsync",
"sys_fdatasync",
"sys_sync_file_range",
"sys_timerfd_create",
"sys_timerfd_settime",
"sys_timerfd_gettime",
"sys_utimensat",
"sys_acct",
"sys_capget",
"sys_capset",
"sys_personality",
"sys_exit",
"sys_exit_group",
"sys_waitid",
"sys_set_tid_address",
"sys_unshare",
"sys_futex",
"sys_set_robust_list",
"sys_get_robust_list",
"sys_nanosleep",
"sys_getitimer",
"sys_setitimer",
"sys_kexec_load",
"sys_init_module",
"sys_delete_module",
"sys_timer_create",
"sys_timer_gettime",
"sys_timer_getoverrun",
"sys_timer_settime",
"sys_timer_delete",
"sys_clock_settime",
"sys_clock_gettime",
"sys_clock_getres",
"sys_clock_nanosleep",
"sys_syslog",
"sys_ptrace",
"sys_sched_setparam",
"sys_sched_setscheduler",
"sys_sched_getscheduler",
"sys_sched_getparam",
"sys_sched_setaffinity",
"sys_sched_getaffinity",
"sys_sched_yield",
"sys_sched_get_priority_max",
"sys_sched_get_priority_min",
"sys_sched_rr_get_interval",
"sys_restart_syscall",
"sys_kill",
"sys_tkill",
"sys_tgkill",
"sys_sigaltstack",
"sys_rt_sigsuspend",
"sys_rt_sigaction",
"sys_rt_sigprocmask",
"sys_rt_sigpending",
"sys_rt_sigtimedwait",
"sys_rt_sigqueueinfo",
"sys_rt_sigreturn",
"sys_setpriority",
"sys_getpriority",
"sys_reboot",
"sys_setregid",
"sys_setgid",
"sys_setreuid",
"sys_setuid",
"sys_setresuid",
"sys_getresuid",
"sys_setresgid",
"sys_getresgid",
"sys_setfsuid",
"sys_setfsgid",
"sys_times",
"sys_setpgid",
"sys_getpgid",
"sys_getsid",
"sys_setsid",
"sys_getgroups",
"sys_setgroups",
"sys_uname",
"sys_sethostname",
"sys_setdomainname",
"sys_getrlimit",
"sys_setrlimit",
"sys_getrusage",
"sys_umask",
"sys_prctl",
"sys_getcpu",
"sys_gettimeofday",
"sys_settimeofday",
"sys_adjtimex",
"sys_getpid",
"sys_getppid",
"sys_getuid",
"sys_geteuid",
"sys_getgid",
"sys_getegid",
"sys_gettid",
"sys_sysinfo",
"sys_mq_open",
"sys_mq_unlink",
"sys_mq_timedsend",
"sys_mq_timedreceive",
"sys_mq_notify",
"sys_mq_getsetattr",
"sys_msgget",
"sys_msgctl",
"sys_msgrcv",
"sys_msgsnd",
"sys_semget",
"sys_semctl",
"sys_semtimedop",
"sys_semop",
"sys_shmget",
"sys_shmctl",
"sys_shmat",
"sys_shmdt",
"sys_socket",
"sys_socketpair",
"sys_bind",
"sys_listen",
"sys_accept",
"sys_connect",
"sys_getsockname",
"sys_getpeername",
"sys_sendto",
"sys_recvfrom",
"sys_setsockopt",
"sys_getsockopt",
"sys_shutdown",
"sys_sendmsg",
"sys_recvmsg",
"sys_readahead",
"sys_brk",
"sys_munmap",
"sys_mremap",
"sys_add_key",
"sys_request_key",
"sys_keyctl",
"sys_clone",
"sys_execve",
"sys_mmap",
"sys_fadvise64",
"sys_swapon",
"sys_swapoff",
"sys_mprotect",
"sys_msync",
"sys_mlock",
"sys_munlock",
"sys_mlockall",
"sys_munlockall",
"sys_mincore",
"sys_madvise",
"sys_remap_file_pages",
"sys_mbind",
"sys_get_mempolicy",
"sys_set_mempolicy",
"sys_migrate_pages",
"sys_move_pages",
"sys_rt_tgsigqueueinfo",
"sys_perf_event_open",
"sys_accept4",
"sys_recvmmsg",
"sys_reserved",
"sys_reserved",
"sys_reserved",
"sys_reserved",
"sys_reserved",
"sys_reserved",
"sys_reserved",
"sys_reserved",
"sys_reserved",
"sys_reserved",
"sys_reserved",
"sys_reserved",
"sys_reserved",
"sys_reserved",
"sys_reserved",
"sys_reserved",
"sys_wait4",
"sys_prlimit64",
"sys_fanotify_init",
"sys_fanotify_mark",
"sys_name_to_handle_at",
"sys_open_by_handle_at",
"sys_clock_adjtime",
"sys_syncfs",
"sys_setns",
"sys_sendmmsg",
"sys_process_vm_readv",
"sys_process_vm_writev",
"sys_kcmp",
"sys_finit_module",
"sys_sched_setattr",
"sys_sched_getattr",
"sys_renameat2",
"sys_seccomp",
"sys_getrandom",
"sys_memfd_create",
"sys_bpf",
"sys_execveat",
"sys_userfaultfd",
"sys_membarrier",
"sys_mlock2",
"sys_copy_file_range",
"sys_preadv2",
"sys_pwritev2",
"sys_pkey_mprotect",
"sys_pkey_alloc",
"sys_pkey_free",
"sys_statx",
"sys_io_pgetevents",
"sys_rseq",
"sys_kexec_file_load",
]
+ ["sys_null" for idx in xrange(295, 424, 1)]
+ SYSCALL_COMMON
)
# syscall for x86 #
SYSCALL_X86 = (
[
"sys_restart_syscall",
"sys_exit",
"sys_fork",
"sys_read",
"sys_write",
"sys_open",
"sys_close",
"sys_waitpid",
"sys_creat",
"sys_link",
"sys_unlink",
"sys_execve",
"sys_chdir",
"sys_time",
"sys_mknod",
"sys_chmod",
"sys_lchown",
"sys_break",
"sys_oldstat",
"sys_lseek",
"sys_getpid",
"sys_mount",
"sys_umount",
"sys_setuid",
"sys_getuid",
"sys_stime",
"sys_ptrace",
"sys_alarm",
"sys_oldfstat",
"sys_pause",
"sys_utime",
"sys_stty",
"sys_gtty",
"sys_access",
"sys_nice",
"sys_ftime",
"sys_sync",
"sys_kill",
"sys_rename",
"sys_mkdir",
"sys_rmdir",
"sys_dup",
"sys_pipe",
"sys_times",
"sys_prof",
"sys_brk",
"sys_setgid",
"sys_getgid",
"sys_signal",
"sys_geteuid",
"sys_getegid",
"sys_acct",
"sys_umount2",
"sys_lock",
"sys_ioctl",
"sys_fcntl",
"sys_mpx",
"sys_setpgid",
"sys_ulimit",
"sys_oldolduname",
"sys_umask",
"sys_chroot",
"sys_ustat",
"sys_dup2",
"sys_getppid",
"sys_getpgrp",
"sys_setsid",
"sys_sigaction",
"sys_sgetmask",
"sys_ssetmask",
"sys_setreuid",
"sys_setregid",
"sys_sigsuspend",
"sys_sigpending",
"sys_sethostname",
"sys_setrlimit",
"sys_getrlimit",
"sys_getrusage",
"sys_gettimeofday",
"sys_settimeofday",
"sys_getgroups",
"sys_setgroups",
"sys_select",
"sys_symlink",
"sys_oldlstat",
"sys_readlink",
"sys_uselib",
"sys_swapon",
"sys_reboot",
"sys_readdir",
"sys_mmap",
"sys_munmap",
"sys_truncate",
"sys_ftruncate",
"sys_fchmod",
"sys_fchown",
"sys_getpriority",
"sys_setpriority",
"sys_profil",
"sys_statfs",
"sys_fstatfs",
"sys_ioperm",
"sys_socketcall",
"sys_syslog",
"sys_setitimer",
"sys_getitimer",
"sys_stat",
"sys_lstat",
"sys_fstat",
"sys_olduname",
"sys_iopl",
"sys_vhangup",
"sys_idle",
"sys_vm86old",
"sys_wait4",
"sys_swapoff",
"sys_sysinfo",
"sys_ipc",
"sys_fsync",
"sys_sigreturn",
"sys_clone",
"sys_setdomainname",
"sys_uname",
"sys_modify_ldt",
"sys_adjtimex",
"sys_mprotect",
"sys_sigprocmask",
"sys_create_module",
"sys_init_module",
"sys_delete_module",
"sys_get_kernel_syms",
"sys_quotactl",
"sys_getpgid",
"sys_fchdir",
"sys_bdflush",
"sys_sysfs",
"sys_personality",
"sys_afs_syscall",
"sys_setfsuid",
"sys_setfsgid",
"sys_llseek",
"sys_getdents",
"sys_newselect",
"sys_flock",
"sys_msync",
"sys_readv",
"sys_writev",
"sys_getsid",
"sys_fdatasync",
"sys_sysctl",
"sys_mlock",
"sys_munlock",
"sys_mlockall",
"sys_munlockall",
"sys_sched_setparam",
"sys_sched_getparam",
"sys_sched_setscheduler",
"sys_sched_getscheduler",
"sys_sched_yield",
"sys_sched_get_priority_max",
"sys_sched_get_priority_min",
"sys_sched_rr_get_interval",
"sys_nanosleep",
"sys_mremap",
"sys_setresuid",
"sys_getresuid",
"sys_vm86",
"sys_query_module",
"sys_poll",
"sys_nfsservctl",
"sys_setresgid",
"sys_getresgid",
"sys_prctl",
"sys_rt_sigreturn",
"sys_rt_sigaction",
"sys_rt_sigprocmask",
"sys_rt_sigpending",
"sys_rt_sigtimedwait",
"sys_rt_sigqueueinfo",
"sys_rt_sigsuspend",
"sys_pread64",
"sys_pwrite64",
"sys_chown",
"sys_getcwd",
"sys_capget",
"sys_capset",
"sys_sigaltstack",
"sys_sendfile",
"sys_getpmsg",
"sys_putpmsg",
"sys_vfork",
"sys_ugetrlimit",
"sys_mmap2",
"sys_truncate64",
"sys_ftruncate64",
"sys_stat64",
"sys_lstat64",
"sys_fstat64",
"sys_lchown32",
"sys_getuid32",
"sys_getgid32",
"sys_geteuid32",
"sys_getegid32",
"sys_setreuid32",
"sys_setregid32",
"sys_getgroups32",
"sys_setgroups32",
"sys_fchown32",
"sys_setresuid32",
"sys_getresuid32",
"sys_setresgid32",
"sys_getresgid32",
"sys_chown32",
"sys_setuid32",
"sys_setgid32",
"sys_setfsuid32",
"sys_setfsgid32",
"sys_pivot_root",
"sys_mincore",
"sys_madvise",
"sys_getdents64",
"sys_fcntl64",
"sys_null",
"sys_null",
"sys_gettid",
"sys_readahead",
"sys_setxattr",
"sys_lsetxattr",
"sys_fsetxattr",
"sys_getxattr",
"sys_lgetxattr",
"sys_fgetxattr",
"sys_listxattr",
"sys_llistxattr",
"sys_flistxattr",
"sys_removexattr",
"sys_lremovexattr",
"sys_fremovexattr",
"sys_tkill",
"sys_sendfile64",
"sys_futex",
"sys_sched_setaffinity",
"sys_sched_getaffinity",
"sys_set_thread_area",
"sys_get_thread_area",
"sys_io_setup",
"sys_io_destroy",
"sys_io_getevents",
"sys_io_submit",
"sys_io_cancel",
"sys_fadvise64",
"sys_set_zone_reclaim",
"sys_exit_group",
"sys_lookup_dcookie",
"sys_epoll_create",
"sys_epoll_ctl",
"sys_epoll_wait",
"sys_remap_file_pages",
"sys_set_tid_address",
"sys_timer_create",
"sys_timer_settime",
"sys_timer_gettime",
"sys_timer_getoverrun",
"sys_timer_delete",
"sys_clock_settime",
"sys_clock_gettime",
"sys_clock_getres",
"sys_clock_nanosleep",
"sys_statfs64",
"sys_fstatfs64",
"sys_tgkill",
"sys_utimes",
"sys_fadvise64_64",
"sys_vserver",
"sys_mbind",
"sys_get_mempolicy",
"sys_set_mempolicy",
"sys_mq_open",
"sys_mq_unlink",
"sys_mq_timedsend",
"sys_mq_timedreceive",
"sys_mq_notify",
"sys_mq_getsetattr",
"sys_kexec_load",
"sys_waitid",
"sys_setaltroot",
"sys_add_key",
"sys_request_key",
"sys_keyctl",
"sys_ioprio_set",
"sys_ioprio_get",
"sys_inotify_init",
"sys_inotify_add_watch",
"sys_inotify_rm_watch",
"sys_migrate_pages",
"sys_openat",
"sys_mkdirat",
"sys_mknodat",
"sys_fchownat",
"sys_futimesat",
"sys_fstatat64",
"sys_unlinkat",
"sys_renameat",
"sys_linkat",
"sys_symlinkat",
"sys_readlinkat",
"sys_fchmodat",
"sys_faccessat",
"sys_pselect6",
"sys_ppoll",
"sys_unshare",
"sys_set_robust_list",
"sys_get_robust_list",
"sys_splice",
"sys_sync_file_range",
"sys_tee",
"sys_vmsplice",
"sys_move_pages",
"sys_getcpu",
"sys_epoll_pwait",
"sys_utimensat",
"sys_signalfd",
"sys_timerfd_create",
"sys_eventfd",
"sys_fallocate",
"sys_timerfd_settime",
"sys_timerfd_gettime",
"sys_signalfd4",
"sys_eventfd2",
"sys_epoll_create1",
"sys_dup3",
"sys_pipe2",
"sys_inotify_init1",
"sys_preadv",
"sys_pwritev",
"sys_rt_tgsigqueueinfo",
"sys_perf_event_open",
"sys_recvmmsg",
"sys_fanotify_init",
"sys_fanotify_mark",
"sys_prlimit64",
"sys_name_to_handle_at",
"sys_open_by_handle_at",
"sys_clock_adjtime",
"sys_syncfs",
"sys_sendmmsg",
"sys_setns",
"sys_process_vm_readv",
"sys_process_vm_writev",
"sys_kcmp",
"sys_finit_module",
"sys_sched_setattr",
"sys_sched_getattr",
"sys_renameat2",
"sys_seccomp",
"sys_getrandom",
"sys_memfd_create",
"sys_bpf",
"sys_execveat",
"sys_socket",
"sys_socketpair",
"sys_bind",
"sys_connect",
"sys_listen",
"sys_accept4",
"sys_getsockopt",
"sys_setsockopt",
"sys_getsockname",
"sys_getpeername",
"sys_sendto",
"sys_sendmsg",
"sys_recvfrom",
"sys_recvmsg",
"sys_shutdown",
"sys_userfaultfd",
"sys_membarrier",
"sys_mlock2",
"sys_copy_file_range",
"sys_preadv2",
"sys_pwritev2",
"sys_pkey_mprotect",
"sys_pkey_alloc",
"sys_pkey_free",
"sys_statx",
"sys_arch_prctl",
"sys_io_pgetevents",
"sys_rseq",
"sys_reserved",
"sys_reserved",
"sys_reserved",
"sys_reserved",
"sys_reserved",
"sys_reserved",
"sys_semget",
"sys_semctl",
"sys_shmget",
"sys_shmctl",
"sys_shmat",
"sys_shmdt",
"sys_msgget",
"sys_msgsnd",
"sys_msgrcv",
"sys_msgctl",
]
+ SYSCALL_COMMON32
+ SYSCALL_COMMON
)
# syscall for x86_64 #
SYSCALL_X64 = (
[
"sys_read",
"sys_write",
"sys_open",
"sys_close",
"sys_stat",
"sys_fstat",
"sys_lstat",
"sys_poll",
"sys_lseek",
"sys_mmap",
"sys_mprotect",
"sys_munmap",
"sys_brk",
"sys_rt_sigaction",
"sys_rt_sigprocmask",
"sys_rt_sigreturn",
"sys_ioctl",
"sys_pread64",
"sys_pwrite64",
"sys_readv",
"sys_writev",
"sys_access",
"sys_pipe",
"sys_select",
"sys_sched_yield",
"sys_mremap",
"sys_msync",
"sys_mincore",
"sys_madvise",
"sys_shmget",
"sys_shmat",
"sys_shmctl",
"sys_dup",
"sys_dup2",
"sys_pause",
"sys_nanosleep",
"sys_getitimer",
"sys_alarm",
"sys_setitimer",
"sys_getpid",
"sys_sendfile",
"sys_socket",
"sys_connect",
"sys_accept",
"sys_sendto",
"sys_recvfrom",
"sys_sendmsg",
"sys_recvmsg",
"sys_shutdown",
"sys_bind",
"sys_listen",
"sys_getsockname",
"sys_getpeername",
"sys_socketpair",
"sys_setsockopt",
"sys_getsockopt",
"sys_clone",
"sys_fork",
"sys_vfork",
"sys_execve",
"sys_exit",
"sys_wait4",
"sys_kill",
"sys_uname",
"sys_semget",
"sys_semop",
"sys_semctl",
"sys_shmdt",
"sys_msgget",
"sys_msgsnd",
"sys_msgrcv",
"sys_msgctl",
"sys_fcntl",
"sys_flock",
"sys_fsync",
"sys_fdatasync",
"sys_truncate",
"sys_ftruncate",
"sys_getdents",
"sys_getcwd",
"sys_chdir",
"sys_fchdir",
"sys_rename",
"sys_mkdir",
"sys_rmdir",
"sys_creat",
"sys_link",
"sys_unlink",
"sys_symlink",
"sys_readlink",
"sys_chmod",
"sys_fchmod",
"sys_chown",
"sys_fchown",
"sys_lchown",
"sys_umask",
"sys_gettimeofday",
"sys_getrlimit",
"sys_getrusage",
"sys_sysinfo",
"sys_times",
"sys_ptrace",
"sys_getuid",
"sys_syslog",
"sys_getgid",
"sys_setuid",
"sys_setgid",
"sys_geteuid",
"sys_getegid",
"sys_setpgid",
"sys_getppid",
"sys_getpgrp",
"sys_setsid",
"sys_setreuid",
"sys_setregid",
"sys_getgroups",
"sys_setgroups",
"sys_setresuid",
"sys_getresuid",
"sys_setresgid",
"sys_getresgid",
"sys_getpgid",
"sys_setfsuid",
"sys_setfsgid",
"sys_getsid",
"sys_capget",
"sys_capset",
"sys_rt_sigpending",
"sys_rt_sigtimedwait",
"sys_rt_sigqueueinfo",
"sys_rt_sigsuspend",
"sys_sigaltstack",
"sys_utime",
"sys_mknod",
"sys_uselib",
"sys_personality",
"sys_ustat",
"sys_statfs",
"sys_fstatfs",
"sys_sysfs",
"sys_getpriority",
"sys_setpriority",
"sys_sched_setparam",
"sys_sched_getparam",
"sys_sched_setscheduler",
"sys_sched_getscheduler",
"sys_sched_get_priority_max",
"sys_sched_get_priority_min",
"sys_sched_rr_get_interval",
"sys_mlock",
"sys_munlock",
"sys_mlockall",
"sys_munlockall",
"sys_vhangup",
"sys_modify_ldt",
"sys_pivot_root",
"sys_sysctl",
"sys_prctl",
"sys_arch_prctl",
"sys_adjtimex",
"sys_setrlimit",
"sys_chroot",
"sys_sync",
"sys_acct",
"sys_settimeofday",
"sys_mount",
"sys_umount2",
"sys_swapon",
"sys_swapoff",
"sys_reboot",
"sys_sethostname",
"sys_setdomainname",
"sys_iopl",
"sys_ioperm",
"sys_create_module",
"sys_init_module",
"sys_delete_module",
"sys_get_kernel_syms",
"sys_query_module",
"sys_quotactl",
"sys_nfsservctl",
"sys_getpmsg",
"sys_putpmsg",
"sys_afs_syscall",
"sys_tuxcall",
"sys_security",
"sys_gettid",
"sys_readahead",
"sys_setxattr",
"sys_lsetxattr",
"sys_fsetxattr",
"sys_getxattr",
"sys_lgetxattr",
"sys_fgetxattr",
"sys_listxattr",
"sys_llistxattr",
"sys_flistxattr",
"sys_removexattr",
"sys_lremovexattr",
"sys_fremovexattr",
"sys_tkill",
"sys_time",
"sys_futex",
"sys_sched_setaffinity",
"sys_sched_getaffinity",
"sys_set_thread_area",
"sys_io_setup",
"sys_io_destroy",
"sys_io_getevents",
"sys_io_submit",
"sys_io_cancel",
"sys_get_thread_area",
"sys_lookup_dcookie",
"sys_epoll_create",
"sys_epoll_ctl_old",
"sys_epoll_wait_old",
"sys_remap_file_pages",
"sys_getdents64",
"sys_set_tid_address",
"sys_restart_syscall",
"sys_semtimedop",
"sys_fadvise64",
"sys_timer_create",
"sys_timer_settime",
"sys_timer_gettime",
"sys_timer_getoverrun",
"sys_timer_delete",
"sys_clock_settime",
"sys_clock_gettime",
"sys_clock_getres",
"sys_clock_nanosleep",
"sys_exit_group",
"sys_epoll_wait",
"sys_epoll_ctl",
"sys_tgkill",
"sys_utimes",
"sys_vserver",
"sys_mbind",
"sys_set_mempolicy",
"sys_get_mempolicy",
"sys_mq_open",
"sys_mq_unlink",
"sys_mq_timedsend",
"sys_mq_timedreceive",
"sys_mq_notify",
"sys_mq_getsetattr",
"sys_kexec_load",
"sys_waitid",
"sys_add_key",
"sys_request_key",
"sys_keyctl",
"sys_ioprio_set",
"sys_ioprio_get",
"sys_inotify_init",
"sys_inotify_add_watch",
"sys_inotify_rm_watch",
"sys_migrate_pages",
"sys_openat",
"sys_mkdirat",
"sys_mknodat",
"sys_fchownat",
"sys_futimesat",
"sys_newfstatat",
"sys_unlinkat",
"sys_renameat",
"sys_linkat",
"sys_symlinkat",
"sys_readlinkat",
"sys_fchmodat",
"sys_faccessat",
"sys_pselect6",
"sys_ppoll",
"sys_unshare",
"sys_set_robust_list",
"sys_get_robust_list",
"sys_splice",
"sys_tee",
"sys_sync_file_range",
"sys_vmsplice",
"sys_move_pages",
"sys_utimensat",
"sys_epoll_pwait",
"sys_signalfd",
"sys_timerfd_create",
"sys_eventfd",
"sys_fallocate",
"sys_timerfd_settime",
"sys_timerfd_gettime",
"sys_accept4",
"sys_signalfd4",
"sys_eventfd2",
"sys_epoll_create1",
"sys_dup3",
"sys_pipe2",
"sys_inotify_init1",
"sys_preadv",
"sys_pwritev",
"sys_rt_tgsigqueueinfo",
"sys_perf_event_open",
"sys_recvmmsg",
"sys_fanotify_init",
"sys_fanotify_mark",
"sys_prlimit64",
"sys_name_to_handle_at",
"sys_open_by_handle_at",
"sys_clock_adjtime",
"sys_syncfs",
"sys_sendmmsg",
"sys_setns",
"sys_getcpu",
"sys_process_vm_readv",
"sys_process_vm_writev",
"sys_kcmp",
"sys_finit_module",
"sys_sched_setattr",
"sys_sched_getattr",
"sys_renameat2",
"sys_seccomp",
"sys_getrandom",
"sys_memfd_create",
"sys_kexec_file_load",
"sys_bpf",
"sys_execveat",
"sys_userfaultfd",
"sys_membarrier",
"sys_mlock2",
"sys_copy_file_range",
"sys_preadv2",
"sys_pwritev2",
"sys_pkey_mprotect",
"sys_pkey_alloc",
"sys_pkey_free",
"sys_statx",
"sys_io_pgetevents",
"sys_rseq",
]
+ ["sys_null" for idx in xrange(335, 424, 1)]
+ SYSCALL_COMMON
)
# default syscall list #
sysList = []
# default register list #
regList = []
# registers sorted by number #
REGS_X86 = [
"eax",
"ecx",
"edx",
"ebx",
"esp",
"ebp", # 5 #
"esi",
"edi",
"eip",
"eflags",
"", # 10 #
"st0",
"st1",
"st2",
"st3",
"st4", # 15 #
"st5",
"st6",
"st7",
"",
"", # 20 #
"xmm0",
"xmm1",
"xmm2",
"xmm3",
"xmm4", # 25 #
"xmm5",
"xmm6",
"xmm7",
"mm0",
"mm1", # 30 #
"mm2",
"mm3",
"mm4",
"mm5",
"mm6", # 35 #
"mm7",
"fcw",
"fsw",
"mxcsr",
"es", # 40 #
"cs",
"ss",
"ds",
"fs",
"gs", # 45 #
"",
"",
"tr",
"ldtr",
]
REGS_X64 = [
"rax",
"rdx",
"rcx",
"rbx",
"rsi",
"rdi", # 5 #
"rbp",
"rsp",
"r8",
"r9",
"r10", # 10 #
"r11",
"r12",
"r13",
"r14",
"r15", # 15 #
"rip",
"xmm0",
"xmm1",
"xmm2",
"xmm3", # 20 #
"xmm4",
"xmm5",
"xmm6",
"xmm7",
"xmm8", # 25 #
"xmm9",
"xmm10",
"xmm11",
"xmm12",
"xmm13", # 30 #
"xmm14",
"xmm15",
"st0",
"st1",
"st2", # 35 #
"st3",
"st4",
"st5",
"st6",
"st7", # 40 #
"mm0",
"mm1",
"mm2",
"mm3",
"mm4", # 45 #
"mm5",
"mm6",
"mm7",
"rflags",
"es", # 50 #
"cs",
"ss",
"ds",
"fs",
"gs", # 55 #
"",
"",
"fs.base",
"gs.base",
"", # 60 #
"",
"tr",
"ldtr",
"mxcsr",
"fcw", # 65 #
"fsw",
]
REGS_ARM = ["r%d" % idx for idx in xrange(16)]
REGS_AARCH64 = (
["x%d" % idx for idx in xrange(31)]
+ ["sp", "pc", "ELP_mode", "RA_SIGN_STATE", "", ""]
+ ["reserved" for idx in xrange(37, 46, 1)]
+ ["VG", "FFR"]
+ ["p%d" % idx for idx in xrange(16)]
+ ["v%d" % idx for idx in xrange(32)]
+ ["z%d" % idx for idx in xrange(32)]
)
pcRegIndex = {
"arm": REGS_ARM.index("r14"),
"aarch64": REGS_AARCH64.index("pc"),
"x86": REGS_X86.index("eip"),
"x64": REGS_X64.index("rip"),
}
# syscall register #
SYSREG_LIST = {
"powerpc": "gpr0",
"arm": "r7",
"aarch64": "x8",
"x64": "orig_rax",
"x86": "orig_eax",
}
# return register #
RET_LIST = {
"powerpc": "result",
"arm": "r0",
"aarch64": "x0",
"x64": "rax",
"x86": "eax",
}
# signal for Linux #
SIG_LIST = [
"0",
"SIGHUP",
"SIGINT",
"SIGQUIT",
"SIGILL", # 4
"SIGTRAP",
"SIGABRT",
"SIGBUS",
"SIGFPE", # 8
"SIGKILL",
"SIGUSR1",
"SIGSEGV",
"SIGUSR2", # 12
"SIGPIPE",
"SIGALRM",
"SIGTERM",
"SIGSTKFLT", # 16
"SIGCHLD",
"SIGCONT",
"SIGSTOP",
"SIGTSTP", # 20
"SIGTTIN",
"SIGTTOU",
"SIGURG",
"SIGXCPU", # 24
"SIGXFSZ",
"SIGVTALRM",
"SIGPROF",
"SIGWINCH", # 28
"SIGIO",
"SIGPWR",
"SIGSYS",
"NONE",
"NONE",
] + ["SIGRT%d" % idx for idx in xrange(32)]
SIGKILL = SIG_LIST.index("SIGKILL")
# signal for MacOS #
SIG_LIST_MACOS = [
"0",
"SIGHUP",
"SIGINT",
"SIGQUIT",
"SIGILL", # 4
"SIGTRAP",
"SIGABRT",
"SIGEMT",
"SIGFPE", # 8
"SIGKILL",
"SIGBUS",
"SIGSEGV",
"SIGSYS", # 12
"SIGPIPE",
"SIGALRM",
"SIGTERM",
"SIGURG", # 16
"SIGSTOP",
"SIGTSTP",
"SIGCONT",
"SIGCHLD", # 20
"SIGTTIN",
"SIGTTOU",
"SIGIO",
"SIGXCPU", # 24
"SIGXFSZ",
"SIGVTALRM",
"SIGPROF",
"SIGWINCH", # 28
"SIGINFO",
"SIGUSR1",
"SIGUSR2", # 31
]
# SIGCHLD si_codes #
SIGCHLD_CODE = [
"N/A",
"CLD_EXITED", # /* child has exited */
"CLD_KILLED", # /* child was killed */
"CLD_DUMPED", # /* child terminated abnormally */
"CLD_TRAPPED", # /* traced child has trapped */
"CLD_STOPPED", # /* child has stopped */
"CLD_CONTINUED", # /* stopped child has continued */
]
# SIGSEGV si_codes #
SIGSEGV_CODE = [
"N/A",
"SEGV_MAPERR", # /* address not mapped to object */
"SEGV_ACCERR", # /* invalid permissions for mapped object */
"SEGV_BNDERR", # /* failed address bound checks */
"SEGV_PSTKOVF", # /* paragraph stack overflow */
"SEGV_ACCADI", # /* ADI not enabled for mapped object */
"SEGV_ADIDERR", # /* Disrupting MCD error */
"SEGV_ADIPERR", # /* Precise MCD exception */
"SEGV_MTEAERR", # /* Asynchronous ARM MTE error */
"SEGV_MTESERR", # /* Synchronous ARM MTE exception */
]
# SIGILL si_codes #
SIGILL_CODE = [
"N/A",
"ILL_ILLOPC", # /* illegal opcode */
"ILL_ILLOPN", # /* illegal operand */
"ILL_ILLADR", # /* illegal addressing mode */
"ILL_ILLTRP", # /* illegal trap */
"ILL_PRVOPC", # /* privileged opcode */
"ILL_PRVREG", # /* privileged register */
"ILL_COPROC", # /* coprocessor error */
"ILL_BADSTK", # /* internal stack error */
"ILL_BADIADDR", # /* unimplemented instruction address */
"__ILL_BREAK", # /* illegal break */
"__ILL_BNDMOD", # /* bundle-update (modification) in progress */
]
# SIGTRAP si_codes #
SIGTRAP_CODE = [
"N/A",
"TRAP_BRKPT", # /* process breakpoint */
"TRAP_TRACE", # /* process trace trap */
"TRAP_BRANCH", # /* process taken branch trap */
"TRAP_HWBKPT", # /* hardware breakpoint/watchpoint */
"TRAP_UNK", # /* undiagnosed trap */
]
# SIGFPE si_codes #
SIGFPE_CODE = [
"N/A",
"FPE_INTDIV", # /* integer divide by zero */
"FPE_INTOVF", # /* integer overflow */
"FPE_FLTDIV", # /* floating point divide by zero */
"FPE_FLTOVF", # /* floating point overflow */
"FPE_FLTUND", # /* floating point underflow */
"FPE_FLTRES", # /* floating point inexact result */
"FPE_FLTINV", # /* floating point invalid operation */
"FPE_FLTSUB", # /* subscript out of range */
"__FPE_DECOVF", # /* decimal overflow */
"__FPE_DECDIV", # /* decimal division by zero */
"__FPE_DECERR", # /* packed decimal error */
"__FPE_INVASC", # /* invalid ASCII digit */
"__FPE_INVDEC", # /* invalid decimal digit */
"FPE_FLTUNK", # /* undiagnosed floating-point exception */
"FPE_CONDTRAP", # /* trap on condition */
]
# si_codes #
SI_CODE = {
0: "SI_USER", # /* sent by kill, sigsend, raise */
0x80: "SI_KERNEL", # /* sent by the kernel from somewhere */
-1: "SI_QUEUE", # /* sent by sigqueue */
-2: "SI_TIMER", # /* sent by timer expiration */
-3: "SI_MESGQ", # /* sent by real time mesq state change */
-4: "SI_ASYNCIO", # /* sent by AIO completion */
-5: "SI_SIGIO", # /* sent by queued SIGIO */
-6: "SI_TKILL", # /* sent by tkill system call */
-7: "SI_DETHREAD", # /* sent by execve() killing subsidiary threads */
-60: "SI_ASYNCNL", # /* sent by glibc async name lookup completion */
}
# stat fields from http://linux.die.net/man/5/proc #
STAT_ATTR = [
"PID",
"COMM",
"STATE",
"PPID",
"PGRP",
"SESSIONID", # 5
"NRTTY",
"TPGID",
"FLAGS",
"MINFLT",
"CMINFLT", # 10
"MAJFLT",
"CMAJFLT",
"UTIME",
"STIME",
"CUTIME", # 15
"CSTIME",
"PRIORITY",
"NICE",
"NRTHREAD",
"ITERALVAL", # 20
"STARTTIME",
"VSIZE",
"RSS",
"RSSLIM",
"STARTCODE", # 25
"ENDCODE",
"STARTSTACK",
"SP",
"PC",
"SIGNAL", # 30
"BLOCKED",
"SIGIGNORE",
"SIGCATCH",
"WCHEN",
"NSWAP", # 35
"CNSWAP",
"EXITSIGNAL",
"PROCESSOR",
"RTPRIORITY", # 39
"POLICY",
"DELAYBLKTICK",
"GUESTTIME",
"CGUESTTIME",
"STARTDATA", # 44
"ENDDATA",
"STARTBRK",
"ARGSTART",
"ARGEND", # 48
"ENVSTART",
"ENVEND",
"EXITCODE", # 51
]
# sched policy #
SCHED_POLICY = [
"C", # 0: CFS #
"F", # 1: FIFO #
"R", # 2: RR #
"B", # 3: BATCH #
"N", # 4: NONE #
"I", # 5: IDLE #
"D", # 6: DEADLINE #
]
# sched policy for Windows #
SCHED_POLICY_WINDOWS = {
"ABOVE_NORMAL_PRIORITY_CLASS": "ANOR",
"BELOW_NORMAL_PRIORITY_CLASS": "BNOR",
"HIGH_PRIORITY_CLASS": "HIGH",
"IDLE_PRIORITY_CLASS": "IDLE",
"NORMAL_PRIORITY_CLASS": "NORM",
"PROCESS_MODE_BACKGROUND_BEGIN": "BGBE",
"PROCESS_MODE_BACKGROUND_END": "BGEN",
"REALTIME_PRIORITY_CLASS": "RT",
}
# I/O sched class #
IOSCHED_CLASS = [
"NONE",
"IOPRIO_CLASS_RT",
"IOPRIO_CLASS_BE",
"IOPRIO_CLASS_IDLE",
]
# I/O sched target #
IOSCHED_TARGET = [
"NONE",
"IOPRIO_WHO_PROCESS",
"IOPRIO_WHO_PGRP",
"IOPRIO_WHO_USER",
]
# statm fields #
STATM_TYPE = [
"TOTAL", # 0 #
"RSS", # 1 #
"SHR", # 2 #
"TEXT", # 3 #
"DATA", # 4 #
"LIB", # 5 #
"DIRTY", # 6 #
]
# error types #
ERR_TYPE = [
"EPERM", # Operation not permitted #
"ENOENT", # No such file or directory #
"ESRCH", # No such process #
"EINTR", # Interrupted system call #
"EIO", # I/O error #
"ENXIO", # No such device or address #
"E2BIG", # Argument list too long #
"ENOEXEC", # Exec format error #
"EBADF", # Bad file number #
"ECHILD", # No child processes #
"EAGAIN", # Try again #
"ENOMEM", # Out of memory #
"EACCES", # Permission denied #
"EFAULT", # Bad address #
"ENOTBLK", # Block device required #
"EBUSY", # Device or resource busy #
"EEXIST", # File exists #
"EXDEV", # Cross-device link #
"ENODEV", # No such device #
"ENOTDIR", # Not a directory #
"EISDIR", # Is a directory #
"EINVAL", # Invalid argument #
"ENFILE", # File table overflow #
"EMFILE", # Too many open files #
"ENOTTY", # Not a typewriter #
"ETXTBSY", # Text file busy #
"EFBIG", # File too large #
"ENOSPC", # No space left on device #
"ESPIPE", # Illegal seek #
"EROFS", # Read-only file system #
"EMLINK", # Too many links #
"EPIPE", # Broken pipe #
"EDOM", # Math argument out of domain of func #
"ERANGE", # Math result not representable #
"EDEADLK", # Resource deadlock would occur #
"ENAMETOOLONG", # File name too long #
"ENOLCK", # No record locks available #
"ENOSYS", # Function not implemented #
"ENOTEMPTY", # Directory not empty #
"ELOOP", # Too many symbolic links encountered #
"EWOULDBLOCK", # Operation would block #
"ENOMSG", # No message of desired type #
"EIDRM", # Identifier removed #
"ECHRNG", # Channel number out of range #
"EL2NSYNC", # Level 2 not synchronized #
"EL3HLT", # Level 3 halted #
"EL3RST", # Level 3 reset #
"ELNRNG", # Link number out of range #
"EUNATCH", # Protocol driver not attached #
"ENOCSI", # No CSI structure available #
"EL2HLT", # Level 2 halted #
"EBADE", # Invalid exchange #
"EBADR", # Invalid request descriptor #
"EXFULL", # Exchange full #
"ENOANO", # No anode #
"EBADRQC", # Invalid request code #
"EBADSLT ", # Invalid slot #
"EDEADLOCK",
"EBFONT", # Bad font file format #
"ENOSTR", # Device not a stream #
"ENODATA", # No data available #
"ETIME", # Timer expired #
"ENOSR", # Out of streams resources #
"ENONET", # Machine is not on the network #
"ENOPKG", # Package not installed #
"EREMOTE", # Object is remote #
"ENOLINK", # Link has been severed #
"EADV", # Advertise error #
"ESRMNT", # Srmount error #
"ECOMM", # Communication error on send #
"EPROTO", # Protocol error #
"EMULTIHOP", # Multihop attempted #
"EDOTDOT", # RFS specific error #
"EBADMSG", # Not a data message #
"EOVERFLOW", # Value too large for defined data type #
"ENOTUNIQ", # Name not unique on network #
"EBADFD", # File descriptor in bad state #
"EREMCHG", # Remote address changed #
"ELIBACC", # Can not access a needed shared library #
"ELIBBAD", # Accessing a corrupted shared library #
"ELIBSCN", # .lib section in a.out corrupted #
"ELIBMAX", # Attempting to link in too many shared libraries #
"ELIBEXEC", # Cannot exec a shared library directly #
"EILSEQ", # Illegal byte sequence #
"ERESTART", # Interrupted system call should be restarted #
"ESTRPIPE", # Streams pipe error #
"EUSERS", # Too many users #
"ENOTSOCK", # Socket operation on non-socket #
"EDESTADDRREQ", # Destination address required #
"EMSGSIZE", # Message too long #
"EPROTOTYPE", # Protocol wrong type for socket #
"EPROTOTYPE", # Protocol wrong type for socket #
"ENOPROTOOPT", # Protocol not available #
"EPROTONOSUPPORT", # Protocol not supported #
"ESOCKTNOSUPPORT", # Socket type not supported #
"EOPNOTSUPP", # Operation not supported on transport endpoint #
"EPFNOSUPPORT", # Protocol family not supported #
"EAFNOSUPPORT ", # Address family not supported by protocol #
"EADDRINUSE ", # Address already in use #
"EADDRNOTAVAIL", # Cannot assign requested address #
"ENETDOWN", # Network is down #
"ENETUNREACH", # Network is unreachable #
"ENETRESET", # Network dropped connection because of reset #
"ECONNABORTED", # Software caused connection abort #
"ECONNRESET", # Connection reset by peer #
"ENOBUFS", # No buffer space available #
"EISCONN", # Transport endpoint is already connected #
"ENOTCONN", # Transport endpoint is not connected #
"ESHUTDOWN", # Cannot send after transport endpoint shutdown #
"ETOOMANYREFS", # Too many references: cannot splice #
"ETIMEDOUT", # Connection timed out #
"ECONNREFUSED", # Connection refused #
"EHOSTDOWN", # Host is down #
"EHOSTUNREACH", # No route to host #
"EALREADY", # Operation already in progress #
"EINPROGRESS", # Operation now in progress #
"ESTALE", # Stale NFS file handle #
"EUCLEAN", # Structure needs cleaning #
"ENOTNAM", # Not a XENIX named type file #
"ENAVAIL", # No XENIX semaphores available #
"EISNAM", # Is a named type file #
"EREMOTEIO", # Remote I/O error #
"EDQUOT", # Quota exceeded #
"ENOMEDIUM", # No medium found #
"EMEDIUMTYPE", # Wrong medium type #
"ECANCELED", # Operation Canceled #
"ENOKEY", # Required key not available #
"EKEYEXPIRED", # Key has expired #
"EKEYREVOKED", # Key has been revoked #
"EKEYREJECTED", # Key was rejected by service #
"EOWNERDEAD", # Owner died #
"ENOTRECOVERABLE", # State not recoverable #
"ERFKILL", # Operation not possible due to RF-kill #
"EHWPOISON", # Memory page has hardware error #
]
# rlimit types #
RLIMIT_TYPE = [
"RLIMIT_CPU",
"RLIMIT_FSIZE",
"RLIMIT_DATA",
"RLIMIT_STACK",
"RLIMIT_CORE",
"RLIMIT_RSS",
"RLIMIT_NPROC",
"RLIMIT_NOFILE",
"RLIMIT_MEMLOCK",
"RLIMIT_AS",
"RLIMIT_LOCKS",
"RLIMIT_SIGPENDING",
"RLIMIT_MSGQUEUE",
"RLIMIT_NICE",
"RLIMIT_RTPRIO",
"RLIMIT_RTTIME",
"RLIMIT_NLIMITS",
]
# UDP/TCP format #
PROTOCOL_ATTR = [
"sl",
"local_address",
"rem_address",
"st",
"tx_rx_queue",
"tr_tm->when",
"retrnsmt",
"uid",
"timeout",
"inode",
"ref",
"pointer",
"drops",
]
# UDS format #
UDS_ATTR = [
"Num",
"RefCount",
"Protocol",
"Flags",
"Type",
"St",
"Inode",
"Path",
]
TCP_STAT = [
"N/A",
"ESTABLISHED",
"SYN_SENT",
"SYN_RECV",
"FIN_WAIT1",
"FIN_WAIT2",
"TIME_WAIT",
"CLOSE",
"CLOSE_WAIT",
"LAST_ACK",
"LISTEN",
"CLOSING",
]
# futex operation flags #
FUTEX_TYPE = [
"FUTEX_WAIT",
"FUTEX_WAKE",
"FUTEX_FD",
"FUTEX_REQUEUE",
"FUTEX_CMP_REQUEUE",
"FUTEX_WAKE_OP",
"FUTEX_LOCK_PI",
"FUTEX_UNLOCK_PI",
"FUTEX_TRYLOCK_PI",
"FUTEX_WAIT_BITSET",
"FUTEX_WAKE_BITSET",
"FUTEX_WAIT_REQUEUE_PI",
"FUTEX_CMP_REQUEUE_PI",
]
# fcntl command flags #
FCNTL_TYPE = [
"F_DUPFD",
"F_GETFD",
"F_SETFD",
"F_GETFL",
"F_SETFL",
"F_GETOWN",
"F_SETOWN",
"F_GETLK",
"F_SETLK",
"F_SETLKW",
]
# ipc call flags #
IPC_TYPE = {
1: "SEMOP",
2: "SEMGET",
3: "SEMCTL",
4: "SEMTIMEDOP",
11: "MSGSND",
12: "MSGRCV",
13: "MSGGET",
14: "MSGCTL",
21: "SHMAT",
22: "SHMDT",
23: "SHMGET",
24: "SHMCTL",
}
# ioring_enter flags #
IORING_ENTER_FLAG = {
1: "IORING_ENTER_GETEVENTS",
2: "IORING_ENTER_SQ_WAKEUP",
4: "IORING_ENTER_SQ_WAIT",
8: "IORING_ENTER_EXT_ARG",
16: "IORING_ENTER_REGISTERED_RING",
}
# ioring_register opcode #
IORING_REGISTER_OPCODE = [
"IORING_REGISTER_BUFFERS",
"IORING_UNREGISTER_BUFFERS",
"IORING_REGISTER_FILES",
"IORING_UNREGISTER_FILES",
"IORING_REGISTER_EVENTFD",
"IORING_UNREGISTER_EVENTFD",
"IORING_REGISTER_FILES_UPDATE",
"IORING_REGISTER_EVENTFD_ASYNC",
"IORING_REGISTER_PROBE",
"IORING_REGISTER_PERSONALITY",
"IORING_UNREGISTER_PERSONALITY",
"IORING_REGISTER_RESTRICTIONS",
"IORING_REGISTER_ENABLE_RINGS",
"IORING_REGISTER_FILES2",
"IORING_REGISTER_FILES_UPDATE2",
"IORING_REGISTER_BUFFERS2",
"IORING_REGISTER_BUFFERS_UPDATE",
"IORING_REGISTER_IOWQ_AFF",
"IORING_UNREGISTER_IOWQ_AFF",
"IORING_REGISTER_IOWQ_MAX_WORKERS",
"IORING_REGISTER_RING_FDS",
"IORING_UNREGISTER_RING_FDS",
"IORING_REGISTER_PBUF_RING",
"IORING_UNREGISTER_PBUF_RING",
"IORING_REGISTER_SYNC_CANCEL",
"IORING_REGISTER_FILE_ALLOC_RANGE",
]
# ioring_param features #
IORING_PARAM_FEATURES = {
0x1: "IORING_FEAT_SINGLE_MMAP",
0x2: "IORING_FEAT_NODROP",
0x4: "IORING_FEAT_SUBMIT_STABLE",
0x8: "IORING_FEAT_RW_CUR_POS",
0x16: "IORING_FEAT_CUR_PERSONALITY",
0x32: "IORING_FEAT_FAST_POLL",
0x64: "IORING_FEAT_POLL_32BITS",
0x128: "IORING_FEAT_SQPOLL_NONFIXED",
0x256: "IORING_FEAT_EXT_ARG",
0x512: "IORING_FEAT_NATIVE_WORKERS",
0x1024: "IORING_FEAT_RSRC_TAGS",
0x2048: "IORING_FEAT_CQE_SKIP",
0x4096: "IORING_FEAT_LINKED_FILE",
}
# ioctl flags #
IOCTL_TYPE = {
"TCGETS": 0x5401,
"TCSETS": 0x5402,
"TCSETSW": 0x5403,
"TCSETSF": 0x5404,
"TCGETA": 0x5405,
"TCSETA": 0x5406,
"TCSETAW": 0x5407,
"TCSETAF": 0x5408,
"TCSBRK": 0x5409,
"TCXONC": 0x540A,
"TCFLSH": 0x540B,
"TIOCEXCL": 0x540C,
"TIOCNXCL": 0x540D,
"TIOCSCTTY": 0x540E,
"TIOCGPGRP": 0x540F,
"TIOCSPGRP": 0x5410,
"TIOCOUTQ": 0x5411,
"TIOCSTI": 0x5412,
"TIOCGWINSZ": 0x5413,
"TIOCSWINSZ": 0x5414,
"TIOCMGET": 0x5415,
"TIOCMBIS": 0x5416,
"TIOCMBIC": 0x5417,
"TIOCMSET": 0x5418,
"TIOCGSOFTCAR": 0x5419,
"TIOCSSOFTCAR": 0x541A,
"FIONREAD": 0x541B,
"TIOCLINUX": 0x541C,
"TIOCCONS": 0x541D,
"TIOCGSERIAL": 0x541E,
"TIOCSSERIAL": 0x541F,
"TIOCPKT": 0x5420,
"FIONBIO": 0x5421,
"TIOCNOTTY": 0x5422,
"TIOCSETD": 0x5423,
"TIOCGETD": 0x5424,
"TCSBRKP": 0x5425,
"TIOCSBRK": 0x5427,
"TIOCCBRK": 0x5428,
"TIOCGSID": 0x5429,
"TIOCGRS485": 0x542E,
"TIOCSRS485": 0x542F,
"TCGETX": 0x5432,
"TCSETX": 0x5433,
"TCSETXF": 0x5434,
"TCSETXW": 0x5435,
"FIONCLEX": 0x5450,
"FIOCLEX": 0x5451,
"FIOASYNC": 0x5452,
"TIOCSERCONFIG": 0x5453,
"TIOCSERGWILD": 0x5454,
"TIOCSERSWILD": 0x5455,
"TIOCGLCKTRMIOS": 0x5456,
"TIOCSLCKTRMIOS": 0x5457,
"TIOCSERGSTRUCT": 0x5458,
"TIOCSERGETLSR": 0x5459,
"TIOCSERGETMULTI": 0x545A,
"TIOCSERSETMULTI": 0x545B,
"TIOCMIWAIT": 0x545C,
"TIOCGICOUNT": 0x545D,
}
IOCTL_TYPE_REVERSE = {}
# ptrace request type #
PTRACE_TYPE = [
"PTRACE_TRACEME", # 0
"PTRACE_PEEKTEXT",
"PTRACE_PEEKDATA",
"PTRACE_PEEKUSR",
"PTRACE_POKETEXT",
"PTRACE_POKEDATA",
"PTRACE_POKEUSR",
"PTRACE_CONT",
"PTRACE_KILL",
"PTRACE_SINGLESTEP", # 9
"",
"",
"PTRACE_GETREGS", # 12
"PTRACE_SETREGS", # 13
"PTRACE_GETFPREGS", # 14
"PTRACE_SETFPREGS", # 15
"PTRACE_ATTACH", # 16
"PTRACE_DETACH", # 17
"PTRACE_GETFPXREGS", # 18
"PTRACE_SETFPXREGS", # 19
"",
"",
"",
"PTRACE_SET_SYSCALL", # 23
"PTRACE_SYSCALL", # 24
"",
"",
"",
"",
"",
"",
"PTRACE_SYSEMU", # 31
"PTRACE_SYSEMU_SINGLESTEP", # 32
]
# ptrace event types #
PTRACE_EVENT_TYPE = (
[
"PTRACE_EVENT_NONE",
"PTRACE_EVENT_FORK",
"PTRACE_EVENT_VFORK",
"PTRACE_EVENT_CLONE",
"PTRACE_EVENT_EXEC",
"PTRACE_EVENT_VFORK_DONE",
"PTRACE_EVENT_EXIT",
"PTRACE_EVENT_SECCOMP",
]
+ ["NONE" for idx in xrange(120)]
+ ["PTRACE_EVENT_STOP"]
)
# perf event types #
PERF_EVENT_TYPE = [
"PERF_TYPE_HARDWARE",
"PERF_TYPE_SOFTWARE",
"PERF_TYPE_TRACEPOINT",
"PERF_TYPE_HW_CACHE",
"PERF_TYPE_RAW",
"PERF_TYPE_BREAKPOINT",
]
PERF_HW_EVENT_TYPE = [
"PERF_COUNT_HW_CPU_CYCLES",
"PERF_COUNT_HW_INSTRUCTIONS",
"PERF_COUNT_HW_CACHE_REFERENCES",
"PERF_COUNT_HW_CACHE_MISSES",
"PERF_COUNT_HW_BRANCH_INSTRUCTIONS",
"PERF_COUNT_HW_BRANCH_MISSES",
"PERF_COUNT_HW_BUS_CYCLES",
"PERF_COUNT_HW_STALLED_CYCLES_FRONTEND",
"PERF_COUNT_HW_STALLED_CYCLES_BACKEND",
"PERF_COUNT_HW_REF_CPU_CYCLES",
]
PERF_SW_EVENT_TYPE = [
"PERF_COUNT_SW_CPU_CLOCK",
"PERF_COUNT_SW_TASK_CLOCK",
"PERF_COUNT_SW_PAGE_FAULTS",
"PERF_COUNT_SW_CONTEXT_SWITCHES",
"PERF_COUNT_SW_CPU_MIGRATIONS",
"PERF_COUNT_SW_PAGE_FAULTS_MIN",
"PERF_COUNT_SW_PAGE_FAULTS_MAJ",
"PERF_COUNT_SW_ALIGNMENT_FAULTS",
"PERF_COUNT_SW_EMULATION_FAULTS",
"PERF_COUNT_SW_DUMMY",
"PERF_COUNT_SW_BPF_OUTPUT",
"PERF_COUNT_SW_CGROUP_SWITCHES",
]
PERF_CACHE_EVENT_TYPE = [
"PERF_COUNT_HW_CACHE_L1D",
"PERF_COUNT_HW_CACHE_L1I",
"PERF_COUNT_HW_CACHE_LL",
"PERF_COUNT_HW_CACHE_DTLB",
"PERF_COUNT_HW_CACHE_ITLB",
"PERF_COUNT_HW_CACHE_BPU",
"PERF_COUNT_HW_CACHE_NODE",
]
PERF_CACHE_EVENT_OP = [
"PERF_COUNT_HW_CACHE_OP_READ",
"PERF_COUNT_HW_CACHE_OP_WRITE",
"PERF_COUNT_HW_CACHE_OP_PREFETCH",
]
PERF_CACHE_EVENT_OPRES = [
"PERF_COUNT_HW_CACHE_RESULT_ACCESS",
"PERF_COUNT_HW_CACHE_RESULT_MISS",
]
PERF_EVENT_SAMPLE = {
"PERF_SAMPLE_IP": 1 << 0,
"PERF_SAMPLE_TID": 1 << 1,
"PERF_SAMPLE_TIME": 1 << 2,
"PERF_SAMPLE_ADDR": 1 << 3,
"PERF_SAMPLE_READ": 1 << 4,
"PERF_SAMPLE_CALLCHAIN": 1 << 5,
"PERF_SAMPLE_ID": 1 << 6,
"PERF_SAMPLE_CPU": 1 << 7,
"PERF_SAMPLE_PERIOD": 1 << 8,
"PERF_SAMPLE_STREAM_ID": 1 << 9,
"PERF_SAMPLE_RAW": 1 << 10,
"PERF_SAMPLE_BRANCH_STACK": 1 << 11,
"PERF_SAMPLE_REGS_USER": 1 << 12,
"PERF_SAMPLE_STACK_USER": 1 << 13,
"PERF_SAMPLE_WEIGHT": 1 << 14,
"PERF_SAMPLE_DATA_SRC": 1 << 15,
"PERF_SAMPLE_IDENTIFIER": 1 << 16,
"PERF_SAMPLE_TRANSACTION": 1 << 17,
"PERF_SAMPLE_REGS_INTR": 1 << 18,
"PERF_SAMPLE_PHYS_ADDR": 1 << 19,
"PERF_SAMPLE_AUX": 1 << 20,
"PERF_SAMPLE_CGROUP": 1 << 21,
"PERF_SAMPLE_DATA_PAGE_SIZE": 1 << 22,
"PERF_SAMPLE_CODE_PAGE_SIZE": 1 << 23,
"PERF_SAMPLE_WEIGHT_STRUCT": 1 << 24,
}
PERF_EVENT_READ_FORMAT = {
"PERF_FORMAT_TOTAL_TIME_ENABLED": 1 << 0,
"PERF_FORMAT_TOTAL_TIME_RUNNING": 1 << 1,
"PERF_FORMAT_ID": 1 << 2,
"PERF_FORMAT_GROUP": 1 << 3,
"PERF_FORMAT_LOST": 1 << 4,
"PERF_FORMAT_MAX": 1 << 5,
}
PERF_FLAG = {
"PERF_FLAG_FD_NO_GROUP": 1 << 0,
"PERF_FLAG_FD_OUTPUT": 1 << 1,
"PERF_FLAG_PID_CGROUP": 1 << 2,
"PERF_FLAG_FD_CLOEXEC": 1 << 3,
}
PERF_BRANCH_SAMPLE_SHIFT = [
"PERF_SAMPLE_BRANCH_USER_SHIFT", # user branches #
"PERF_SAMPLE_BRANCH_KERNEL_SHIFT", # kernel branches #
"PERF_SAMPLE_BRANCH_HV_SHIFT", # hypervisor branches #
"PERF_SAMPLE_BRANCH_ANY_SHIFT", # any branch types #
"PERF_SAMPLE_BRANCH_ANY_CALL_SHIFT", # any call branch #
"PERF_SAMPLE_BRANCH_ANY_RETURN_SHIFT", # any return branch #
"PERF_SAMPLE_BRANCH_IND_CALL_SHIFT", # indirect calls #
"PERF_SAMPLE_BRANCH_ABORT_TX_SHIFT", # transaction aborts #
"PERF_SAMPLE_BRANCH_IN_TX_SHIFT", # in transaction #
"PERF_SAMPLE_BRANCH_NO_TX_SHIFT", # not in transaction #
"PERF_SAMPLE_BRANCH_COND_SHIFT", # conditional branches #
"PERF_SAMPLE_BRANCH_CALL_STACK_SHIFT", # call/ret stack #
"PERF_SAMPLE_BRANCH_IND_JUMP_SHIFT", # indirect jumps #
"PERF_SAMPLE_BRANCH_CALL_SHIFT", # direct call #
"PERF_SAMPLE_BRANCH_NO_FLAGS_SHIFT", # no flags #
"PERF_SAMPLE_BRANCH_NO_CYCLES_SHIFT", # no cycles #
"PERF_SAMPLE_BRANCH_TYPE_SAVE_SHIFT", # save branch type #
"PERF_SAMPLE_BRANCH_HW_INDEX_SHIFT", # save low level index of raw branch records #
"PERF_SAMPLE_BRANCH_PRIV_SAVE_SHIFT", # save privilege mode #
]
@staticmethod
def getMmapId():
if SysMgr.arch == "arm":
return SysMgr.getNrSyscall("sys_mmap2")
else:
return SysMgr.getNrSyscall("sys_mmap")
def __init__(self, mode):
pass
def __del__(self):
pass
class UtilMgr(object):
"""Manager for utilities"""
"""
[ TIPS ]
- vim replacement
- PROBLEM: replace all "type(???) is long" with "isinstance(???, (int, long))"
- SOLUTION: %s/type(\(.*\)) is long/isinstance(\1, (int, long)/g
"""
curTime = 0
progressCnt = 0
progressStr = 0
progressChar = {0: "|", 1: "/", 2: "-", 3: "\\"}
@staticmethod
def convHtmlChar(string):
chars = {"<": "<", ">": ">", "&": "&"}
for key, val in chars.items():
string = string.replace(key, val)
return string
@staticmethod
def makeReverseDict(orig, new):
if not new:
for name, value in orig.items():
new[value] = name
@staticmethod
def removeColor(string):
if not SysMgr.ansiObj:
ansi = r"(?:\x1B[@-_]|[\x80-\x9F])[0-?]*[ -/]*[@-~]"
SysMgr.ansiObj = re.compile(ansi)
return SysMgr.ansiObj.sub("", string)
@staticmethod
def convFloat2Str(val):
val = ("%f" % val).rstrip("0")
if val.endswith("."):
val += "0"
return val
@staticmethod
def convStr2Bytes(string):
# build string #
res = ""
for byte in string:
if type(byte) is str:
byte = long(repr(struct.unpack("B", byte)[0]))
bstr = "%x" % byte
res = "{0:s}{1:0>2} ".format(res, bstr)
return res
@staticmethod
def saveTime():
UtilMgr.printTime(update=True, verb=False)
@staticmethod
def getSizeFilterFunc(var="SIZEFILTER"):
# define size filter function #
def _sizeChecker(val):
return True
# check size filter #
if not var in SysMgr.environList:
return _sizeChecker
# get filter values #
try:
filters = SysMgr.environList[var][0]
filterCode = filters[0]
filterValue = UtilMgr.convUnit2Size(filters[1:])
SysMgr.printInfo("applied %s '%s'" % (var, filters))
except SystemExit:
sys.exit(0)
except:
SysMgr.printErr("failed to apply %s '%s'" % (var, filters), True)
sys.exit(-1)
# return function #
if filterCode == "<":
def _sizeChecker(val):
if val < filterValue:
return True
else:
return False
elif filterCode == ">":
def _sizeChecker(val):
if val > filterValue:
return True
else:
return False
elif filterCode == "=":
def _sizeChecker(val):
if val == filterValue:
return True
else:
return False
else:
SysMgr.printErr(
"failed to apply %s '%s' because wrong operation"
% (var, filters)
)
sys.exit(-1)
return _sizeChecker
@staticmethod
def deepcopy(data):
json = SysMgr.getPkg("marshal", False)
if not json:
json = SysMgr.getPkg("json", False)
if json:
return json.loads(json.dumps(data))
else:
return deepcopy(data)
@staticmethod
def printTime(name=None, update=True, verb=True):
# get current time #
now = time.time()
if not UtilMgr.curTime and update:
UtilMgr.curTime = now
return
diff = now - UtilMgr.curTime
# update timestamp #
if update:
UtilMgr.curTime = now
if not verb:
return
# add name #
if name:
prefix = "/ %s" % name
else:
prefix = ""
# print time diff #
string = "[ELAPSED] %f sec %s" % (diff, prefix)
SysMgr.printWarn(string, True)
@staticmethod
def getCommonPart(strings):
try:
return os.path.commonprefix(strings)
except SystemExit:
sys.exit(0)
except:
SysMgr.printErr("failed to get common part of %s" % strings)
sys.exit(-1)
@staticmethod
def callPyFunc(path, fname, *args):
try:
# get function pointer #
fullname = "%s_%s" % (path, fname)
if fullname in SysMgr.externList:
func = SysMgr.externList[fullname]
elif sys.version_info < (3, 0, 0):
execfile(path) # pylint: disable=undefined-variable
SysMgr.externList[fullname] = locals()[fname]
func = SysMgr.externList[fullname]
else:
exec(open(path).read())
SysMgr.externList[fullname] = locals()[fname]
func = SysMgr.externList[fullname]
# call the function and return #
return func(args)
except SystemExit:
sys.exit(0)
except:
SysMgr.printErr(
"failed to call '%s()' from '%s'" % (func, path), True
)
sys.exit(-1)
@staticmethod
def isGzipFile(path):
try:
with open(path, "rb") as fd:
data = fd.read(2)
if struct.unpack("BB", data) == (0x1F, 0x8B):
return True
else:
return False
except SystemExit:
sys.exit(0)
except:
return False
@staticmethod
def sort(l, val=None, reverse=False):
convert = lambda text: float(text) if text.isdigit() else text
alphanum = lambda key: [
convert(c) for c in re.split("([-+]?[0-9]*\.?[0-9]*)", key)
]
if type(l) is list:
l.sort(key=alphanum, reverse=reverse)
return l
elif type(l) is dict:
return sorted(
l.items(),
key=lambda e: alphanum(e[1][val] if val else e[0]),
reverse=reverse,
)
else:
SysMgr.printWarn(
"failed to sort items because '%s' is not supported" % type(l),
True,
)
return l
@staticmethod
def compareSyscallSuperset():
syscallList = (
ConfigMgr.SYSCALL_COMMON
+ ConfigMgr.SYSCALL_COMMON32
+ ConfigMgr.SYSCALL_X86
+ ConfigMgr.SYSCALL_X64
+ ConfigMgr.SYSCALL_ARM
+ ConfigMgr.SYSCALL_AARCH64
)
syscallList = set(syscallList)
protoList = set(
["sys_%s" % name for name in ConfigMgr.SYSCALL_PROTOTYPES]
)
# print final diff list #
SysMgr.printPipe("--- NO PROTOTYPE ---")
for name in sorted(list(syscallList - protoList)):
SysMgr.printPipe(name)
SysMgr.printPipe("\n--- NO DEFINITION ---")
for name in sorted(list(protoList - syscallList)):
SysMgr.printPipe(name)
@staticmethod
def isBitEnabled(num, bits):
if not bits:
return None
try:
num = long(num)
except SystemExit:
sys.exit(0)
except:
num = long(num, 16)
try:
bits = long(bits)
except SystemExit:
sys.exit(0)
except:
bits = long(bits, 16)
if bits & (1 << num - 1):
return True
else:
return False
@staticmethod
def convxrange(targetList):
result = []
for item in targetList:
try:
nums = item.split(":")
if len(nums) == 1:
result.append(item)
elif len(nums) == 2:
for num in xrange(long(nums[0]), long(nums[1]) + 1):
result.append(str(num))
else:
raise Exception()
except SystemExit:
sys.exit(0)
except:
SysMgr.printErr("wrong number range '%s'" % item, True)
sys.exit(-1)
return result
@staticmethod
def unionItem(targetList):
result = []
dictionary = {}
for item in targetList:
if item in dictionary:
continue
result.append(item)
dictionary[item] = None
return result
@staticmethod
def cleanItem(targetList, union=True):
targetType = type(targetList)
if targetType is str:
targetStr = ""
for val in targetList:
if val:
targetStr += val
return targetStr
elif targetType is list:
# remove redundant values #
if union:
targetList = UtilMgr.unionItem(targetList)
# remove empty values #
newList = []
for val in targetList:
val = val.strip()
if val:
newList.append(val)
return newList
else:
return targetList
@staticmethod
def genRangeDict(prefix, startIdx, endIdx, valStart):
dictList = {}
for index in xrange(startIdx, endIdx + 1):
name = "%s%s" % (prefix, index)
value = valStart + index - startIdx
dictList[name] = value
return dictList
@staticmethod
def printHist(table, title, unit, printer=None, newline=""):
if not table:
return
convNum = UtilMgr.convNum
if not printer:
printer = SysMgr.printPipe
# pop stats #
try:
statmin = table.pop("min", None)
statmax = table.pop("max", None)
statcnt = table.pop("cnt", None)
statsum = table.pop("sum", None)
except SystemExit:
sys.exit(0)
except:
pass
printer(
"\n[%s Histogram] (unit:%s)\n%s%s"
% (title, unit, twoLine, newline)
)
printer(
"{0:^21} {1:^17}\n{2:1}{3:1}".format(
"Range", "Count", oneLine, newline
)
)
for digit, cnt in sorted(table.items()):
srange = long(pow(2, digit - 1))
if srange == 0:
erange = 1
else:
erange = long((srange << 1) - 1)
printer(
"{0:10}-{1:>10} {2:>10}({3:5.1f}%){4:1}".format(
convNum(srange),
convNum(erange),
convNum(cnt),
cnt / float(statcnt) * 100,
newline,
)
)
try:
printer(
(
"{0:1}\n{1:^21} {2:>17}\n{3:^21} {4:>17}\n"
"{5:^21} {6:>17}\n{7:^21} {8:>17}\n{0:1}\n"
).format(
oneLine,
"Min",
convNum(statmin),
"Max",
convNum(statmax),
"Cnt",
convNum(statcnt),
"Sum",
convNum(statsum),
)
)
except SystemExit:
sys.exit(0)
except:
pass
@staticmethod
def ungzip(path):
gzip = SysMgr.getPkg("gzip")
return gzip.open(path, "rb").read()
@staticmethod
def unzip(fd, name):
# get pkg #
zlib = SysMgr.getPkg("zlib", False)
if not zlib:
return None, None
# check format #
magic = fd.read(4)
if magic != b"ZLIB":
SysMgr.printWarn(
"wrong zlib magic number '%s' for %s section" % (magic, name)
)
return None, None
compSize = struct.unpack(">Q", fd.read(8))[0]
uncompBytes = b""
decompressor = zlib.decompressobj()
while 1:
chunk = fd.read(SysMgr.PAGESIZE)
if not chunk:
break
uncompBytes += decompressor.decompress(chunk)
uncompBytes += decompressor.flush()
if len(uncompBytes) != compSize:
SysMgr.printWarn(
(
"failed to decompress %s section because "
"decompressed size is wrong [record: %s, actual: %s]"
)
% (name, compSize, len(uncompBytes))
)
return uncompBytes, len(uncompBytes)
@staticmethod
def convList2Histo(items, dtype="float", mult=1):
def _getRangeIdx(value):
if value <= 1:
return 0
digit = 0
while 1:
digit += 1
value = value >> 1
if value == 0:
return digit
if not items:
return None
# convert type #
if dtype == "float":
if type(items[0]) != float:
items = list(map(float, items))
elif dtype == "long":
if type(items[0]) != long:
items = list(map(long, items))
else:
return None
# convert unit #
items = list(map(lambda x: long(x * mult), items))
# get stats #
histDict = {
"max": max(items),
"min": min(items),
"cnt": len(items),
"sum": sum(items),
}
for value in items:
digit = _getRangeIdx(value)
histDict.setdefault(digit, 0)
histDict[digit] += 1
return histDict
@staticmethod
def getSigList():
sigList = dict(
(k, v)
for v, k in reversed(sorted(signal.__dict__.items()))
if v.startswith("SIG") and not v.startswith("SIG_")
)
return sigList
@staticmethod
def getEnvironNum(
name, isExit=True, default=None, verb=True, isInt=False, isFloat=False
):
try:
# get first value #
value = SysMgr.environList[name][0]
# return by type for compatibility #
if isInt:
return int(value)
elif isFloat:
return float(value)
else:
return long(value)
except SystemExit:
sys.exit(0)
except:
if verb:
SysMgr.printErr(
"failed to get the number of %s variable" % name, True
)
if isExit:
sys.exit(-1)
return default
@staticmethod
def parseCommand(option):
if not UtilMgr.isString(option):
return option
stringList = {}
# process strings in "" #
strings = re.findall('"(.*?)"', option)
if strings:
# create an dictionary for strings #
for idx, item in enumerate(strings):
if not item:
continue
val = "#%s#" % idx
stringList.setdefault(item.strip('"'), val)
# replace strings #
for string, value in stringList.items():
option = option.replace('"%s"' % string, value)
# split the option string #
option = option.split(" ")
for string, value in stringList.items():
for idx, item in enumerate(deepcopy(option)):
if value in item:
option[idx] = item.replace(value, string)
return option
@staticmethod
def convList2Dict(optList, sep=":", cap=False):
newDict = {}
for item in optList:
try:
# get values #
values = item.split(sep, 1)
if len(values) == 1:
key = values[0]
value = "SET"
else:
key, value = values
# change to capital #
if cap:
key = key.upper()
# set values #
if key in newDict:
newDict[key].append(value)
else:
newDict[key] = [value]
except SystemExit:
sys.exit(0)
except:
SysMgr.printWarn(
"failed to parse %s by separator %s" % (item, sep)
)
continue
return newDict
@staticmethod
def getStdev(data):
def _variance(data, ddof=0):
n = len(data)
mean = sum(data) / n
return sum((x - mean) ** 2 for x in data) / (n - ddof)
var = _variance(data)
math = SysMgr.getPkg("math")
stdDev = math.sqrt(var)
return stdDev
@staticmethod
def splitString(string):
string = string.replace("\,", "$%")
clist = string.split(",")
for idx, item in enumerate(list(clist)):
clist[idx] = item.replace("$%", ",").strip()
return clist
@staticmethod
def getDrawOutputPath(inputPath, name, suffix=False):
# set output path #
if SysMgr.outPath:
outputPath = SysMgr.outPath
# check dir #
if os.path.isdir(outputPath):
outputFileName = (
"%s.svg" % os.path.splitext(os.path.basename(inputPath))[0]
)
outputPath = os.path.join(outputPath, outputFileName)
elif suffix:
dirName = os.path.dirname(os.path.realpath(inputPath))
fileName = "%s_%s.svg" % (
os.path.splitext(os.path.basename(inputPath))[0],
name,
)
outputPath = os.path.join(dirName, fileName)
else:
outputPath = UtilMgr.prepareForImageFile(inputPath, name)
return os.path.realpath(outputPath)
@staticmethod
def printSyscalls(systable):
bufstring = ""
for idx, syscall in enumerate(systable):
if idx % 4 == 0:
bufstring += "\n"
bufstring = "%s'%s', " % (bufstring, syscall)
sys.exit("%s\ntotal: %s" % (bufstring, len(systable)))
@staticmethod
def isValidStr(string, key=None, inc=False, ignCap=False):
if not key:
if not SysMgr.filterGroup:
return True
key = SysMgr.filterGroup
if ignCap:
string = string.lower()
for cond in list(key):
if not cond:
continue
cond = str(cond)
if ignCap:
cond = cond.lower()
if inc:
if cond in string:
return True
else:
if cond == "*":
return True
elif (
cond.startswith("*")
and cond.endswith("*")
and cond.strip("*") in string
):
return True
elif cond.startswith("*") and string.endswith(cond[1:]):
return True
elif cond.endswith("*") and string.startswith(cond[:-1]):
return True
elif cond == string:
return True
return False
@staticmethod
def convWord2Str(word):
try:
return struct.pack("L", word)
except SystemExit:
sys.exit(0)
except:
SysMgr.printErr("failed to convert word %s to string" % word, True)
return None
@staticmethod
def lstrip(string, wordList):
"""
str.lstrip() removes all heading characters including all characters
in the string argument.
ex) '12345'.lstrip('321') -> '45'
ex) '12345'.lstrip('31') -> '2345'
"""
if type(wordList) != list:
wordList = [wordList]
for word in wordList:
if string.startswith(word):
string = string[len(word) :]
return string
@staticmethod
def rstrip(string, wordList):
"""
str.rstrip() removes all ending characters including all characters
in the string argument.
ex) '12345'.rstrip('543') -> '12'
ex) '12345'.rstrip('53') -> '1234'
"""
if type(wordList) != list:
wordList = [wordList]
for word in wordList:
if string.endswith(word):
return string[: -len(word)]
return string
@staticmethod
def strip(string, wordList):
ret = UtilMgr.lstrip(string, wordList)
ret = UtilMgr.rstrip(ret, wordList)
return ret
@staticmethod
def getInodes(
path,
inodeFilter=[],
nameFilter=[],
exceptFilter=[],
fileAttr=None,
verb=True,
):
inodeList = {}
for r, d, f in os.walk(path):
# get full path for upper dir #
fdir = os.path.realpath(r)
if not FileAnalyzer.isValidFile(fdir):
continue
# print progress #
UtilMgr.printProgress()
for name in f + d:
# get full path for file ##
fpath = os.path.join(fdir, name)
# check name filter #
if nameFilter and not UtilMgr.isValidStr(name, nameFilter):
continue
elif exceptFilter and UtilMgr.isValidStr(fpath, exceptFilter):
continue
# check inode filter #
try:
fstat = os.stat(fpath)
if not fstat:
continue
except SystemExit:
sys.exit(0)
except:
SysMgr.printWarn(
"failed to get stat for %s" % fpath, reason=True
)
continue
# get inode #
inode = str(fstat.st_ino)
if inodeFilter and not inode in inodeFilter:
continue
# make device ID #
major = os.major(fstat.st_dev)
minor = os.minor(fstat.st_dev)
devid = "%s:%s" % (major, minor)
fpath = os.path.join(fdir, name)
# register inode #
inodeList.setdefault(devid, {})
inodeList[devid][inode] = fpath
# register file attribute #
if type(fileAttr) is dict:
fileAttr[fpath] = fstat
return inodeList
@staticmethod
def gerPermutation(inputList, union=False):
visited = [0 for _ in xrange(len(inputList))]
returnList = []
def dfs(cnt, items):
if cnt == len(inputList):
returnList.append(items[:])
return
for i, val in enumerate(inputList):
# check union #
if union and visited[i] == 1:
continue
# add item and check visit flag #
items.append(val)
visited[i] = 1
dfs(cnt + 1, items)
# remove item and uncheck visit flag #
items.pop()
visited[i] = 0
dfs(0, [])
return returnList
@staticmethod
def getPath(path):
# get file info #
filename = os.path.basename(path)
dirname = os.path.dirname(path)
if not dirname:
dirname = "."
return dirname, filename
@staticmethod
def getFiles(path, name=None, incFile=True, incDir=False, recursive=True):
flist = []
for r, d, f in os.walk(path):
if incFile:
for sfile in f:
if name and not UtilMgr.isValidStr(sfile, name):
continue
flist.append(os.path.join(r, sfile))
if incDir:
for sdir in d:
if name and not UtilMgr.isValidStr(sdir, name):
continue
flist.append(os.path.join(r, sdir))
if not recursive:
break
return flist
@staticmethod
def convStr2Time(timestr, timefmt=None, isSec=True):
datetime = SysMgr.getPkg("datetime", False)
if not datetime:
return None
if not timefmt:
timefmt = "%Y-%m-%dT%H:%M:%SZ"
try:
timeObj = datetime.datetime.strptime(timestr, timefmt)
if isSec:
# seconds from UTC 1970-01-01 00:00:00 #
return (
timeObj - datetime.datetime.fromtimestamp(0)
).total_seconds()
else:
return timeObj
except SystemExit:
sys.exit(0)
except:
SysMgr.printWarn(
"failed to convert '%s' to time" % timestr, True, True
)
return None
@staticmethod
def getEpoch2Start(utc=False):
datetime = SysMgr.getPkg("datetime", False)
if not datetime:
return None
# get epoch time #
if utc:
epoch = datetime.datetime.utcnow().timestamp()
else:
epoch = datetime.datetime.now().timestamp()
return epoch - SysMgr.getUptime()
@staticmethod
def getClockTime(ctype="CLOCK_MONOTONIC", dlt=False):
# get ctypes object #
SysMgr.importPkgItems("ctypes")
class timespec(Structure):
_fields_ = [("tv_sec", c_long), ("tv_nsec", c_long)]
# load libc #
SysMgr.loadLibcObj(exit=True)
# define arg types for free() #
SysMgr.libcObj.clock_gettime.argtypes = [c_int, POINTER(timespec)]
# create an object #
t = timespec()
# get time #
ret = SysMgr.libcObj.clock_gettime(
ConfigMgr.CLOCK_TYPE[ctype], pointer(t)
)
if ret != 0:
SysMgr.printErr("failed to get clock %s time" % ctype, True)
return -1
# return time #
if dlt:
return (
c_uint32(t.tv_sec * 10000).value / 10000
+ c_uint32(t.tv_nsec).value / 1000000000
)
else:
return t.tv_sec + t.tv_nsec * 1e-9
@staticmethod
def getTime(utc=False):
datetime = SysMgr.getPkg("datetime", False)
if not datetime:
return None
if utc:
timeobj = datetime.datetime.utcnow()
else:
timeobj = datetime.datetime.now()
return timeobj.strftime("%Y-%m-%dT%H:%M:%SZ")
@staticmethod
def getFileList(flist, sort=False, exceptDir=False):
if not flist or type(flist) is not list:
return []
rlist = []
for item in flist:
item = item.strip()
if item.startswith("-"):
break
# apply regular expression for path #
ilist = UtilMgr.convPath(item)
if not ilist:
SysMgr.printWarn(
"failed to find any file related to '%s'" % item, True
)
elif UtilMgr.isString(ilist):
rlist.append(ilist)
elif type(ilist) is list:
rlist += ilist
# check redundant files #
if len(rlist) != len(set(rlist)):
SysMgr.printWarn(
"detected redundant files in [ %s ]" % ", ".join(rlist), True
)
# exclude dir #
if exceptDir:
newlist = []
for fname in rlist:
if os.path.isdir(fname):
continue
newlist.append(fname)
rlist = newlist
# remove redundant files #
if sort:
return sorted(rlist)
else:
return rlist
@staticmethod
def decodeArg(value):
try:
text = repr(value.decode())
except SystemExit:
sys.exit(0)
except:
text = value
# define start index by encoding type #
if type(text) is bytes:
start = 2
else:
start = 1
return text[start:].rstrip("'")
@staticmethod
def convBin2Str(path, pos=False):
try:
if sys.version_info < (3, 0):
fd = open(path, "rb")
else:
fd = open(path, encoding="latin-1")
content = fd.read()
strList = list(re.findall("[^\x00-\x1F\x7F-\xFF]{4,}", content))
# add position #
if pos:
lastPos = 0
dictList = {}
for item in strList:
dictList.setdefault(item, content.find(item, lastPos))
lastPos = dictList[item]
return dictList
return strList
except SystemExit:
sys.exit(0)
except:
SysMgr.printErr("failed to convert '%s' to strings" % path, True)
return False
@staticmethod
def bisect_left(a, x, lo=0, hi=None):
# copied from python standard library bisect.py #
if lo < 0:
raise ValueError("lo must be non-negative")
if not hi:
hi = len(a)
while lo < hi:
mid = (lo + hi) // 2
if a[mid] <= x:
lo = mid + 1
else:
hi = mid
return lo
@staticmethod
def getFlagBit(vlist, flist):
num = 0
for flag in flist:
try:
num |= vlist[flag]
except:
SysMgr.printErr(
"failed to get %s in [%s]" % (flag, "|".join(list(vlist)))
)
sys.exit(-1)
return num
@staticmethod
def getFlagList(value, flist, num="hex"):
rlist = []
numVal = long(value)
for name, bits in list(flist.items()):
if numVal & bits:
rlist.append(name)
return rlist
@staticmethod
def getFlagString(value, flist, num="hex", zero=False):
string = ""
numVal = long(value)
for bit in list(flist):
try:
if numVal - bit < 0:
break
elif numVal & bit:
string = "%s%s|" % (string, flist[bit])
except SystemExit:
sys.exit(0)
except:
SysMgr.printWarn(
"failed to get flag info for %s" % value, reason=True
)
# check value for 0 index in limited variable range #
if 0 in flist:
if zero:
string = "%s|%s" % (flist[0], string)
elif num == "hex" and numVal & 0xF == 0:
string = "%s|%s" % (flist[0], string)
elif num == "oct" and numVal & 0o7 == 0:
string = "%s|%s" % (flist[0], string)
elif num == "bin" and numVal & 1 == 0:
string = "%s|%s" % (flist[0], string)
if string:
return string[:-1]
else:
return value
@staticmethod
def encodeBase64(value):
base64 = SysMgr.getPkg("base64", False)
try:
return base64.b64encode(value)
except SystemExit:
sys.exit(0)
except:
return value
@staticmethod
def readLEB128(fd):
data = None
while 1:
char = fd.read(1)
if ord(char) & 0x80 == 0:
break
elif not data:
data = char
else:
data += char
return data
@staticmethod
def decodeSLEB128(obj):
size = 1
value = 0
# get size #
for i, b in enumerate(obj):
b = b if type(b) == long else ord(b)
value += (b & 0x7F) << (i * 7)
if (b & 0x80) == 0:
break
size += 1
# decode data #
obj = obj[:size]
if ord(obj[-1]) & 0x40:
# negative -> sign extend
value |= -(1 << (7 * len(obj)))
return value, size
@staticmethod
def decodeULEB128(obj):
size = 1
value = 0
# get size #
for b in obj:
val = b if type(b) == long else ord(b)
if (val & 0x80) == 0:
break
size += 1
# decode data #
for b in reversed(obj[:size]):
b = b if type(b) == long else ord(b)
value = (value << 7) + (b & 0x7F)
return value, size
@staticmethod
def isCompressed(fname=None, fd=None):
# file name #
if fname:
try:
fd = open(fname, "rb")
except SystemExit:
sys.exit(0)
except:
SysMgr.printOpenErr(fname)
sys.exit(-1)
# file descriptor #
if fd:
data = fd.read(2)
fd.seek(0, 0)
if struct.unpack("BB", data) == (0x1F, 0x8B):
return True
else:
return False
# no value #
return False
@staticmethod
def conv2BitStr(content):
return bin(content)
@staticmethod
def decodeBase64(value):
base64 = SysMgr.getPkg("base64", False)
try:
return base64.b64decode(value)
except SystemExit:
sys.exit(0)
except:
return value
@staticmethod
def encodeStr(value):
try:
return value.encode()
except SystemExit:
sys.exit(0)
except:
try:
return value.encode("utf8", "surrogateescape")
except SystemExit:
sys.exit(0)
except:
return value
@staticmethod
def isString(value):
if isinstance(value, str):
return True
elif sys.version_info >= (3, 0, 0):
if isinstance(value, bytes):
return True
elif isinstance(value, unicode): # pylint: disable=undefined-variable
return True
return False
@staticmethod
def isFloat(value):
if type(value) is float:
return True
elif type(value) is str:
try:
float(value)
return True
except SystemExit:
sys.exit(0)
except:
return False
else:
return False
@staticmethod
def isNumber(value):
if isinstance(value, (int, long)):
return True
elif type(value) is str:
if value.isdigit():
return True
try:
if value.startswith("0x") and long(value, 16):
return True
else:
return False
except SystemExit:
sys.exit(0)
except:
return False
else:
return False
@staticmethod
def getTextLines(fname, verb=False, retfd=False, load=True):
buf = []
if verb:
# get output size #
fsize = UtilMgr.getFileSizeStr(fname)
# set job type #
if load:
job = "loading"
else:
job = "checking"
SysMgr.printStat(r"start %s '%s'%s..." % (job, fname, fsize))
# open gzip file #
try:
# check gzip magic number #
if not UtilMgr.isGzipFile(fname):
raise Exception()
compressor = SysMgr.getPkg("gzip", False)
fd = compressor.open(fname, "rt")
except SystemExit:
sys.exit(0)
except:
fd = None
# open normal file #
try:
if not fd:
fd = open(fname, "r", encoding="utf-8")
except SystemExit:
sys.exit(0)
except:
fd = open(fname, "r")
# just return fd #
if retfd:
return fd
# get total size #
try:
totalSize = os.stat(fname).st_size
except SystemExit:
sys.exit(0)
except:
totalSize = 0
# read data from a file #
while 1:
try:
data = fd.readline()
if not data:
break
buf.append(data)
if verb:
UtilMgr.printProgress(fd.tell(), totalSize)
except SystemExit:
sys.exit(0)
except:
break
if verb:
UtilMgr.deleteProgress()
try:
fd.close()
except:
pass
return buf
@staticmethod
def convPath(value, retStr=False, isExit=False, separator=" ", warn=True):
def _convType(retStr, res):
# str #
if retStr:
if res:
return sorted(separator.join(res))
else:
return ""
# list #
else:
if res:
return sorted(res)
else:
return []
# strip path #
value = value.strip()
# all files including hidden files from specific directory recursively #
if value.endswith("/**"):
glob = None
value = UtilMgr.rstrip(value, "/**")
res = []
for r, d, f in os.walk(value):
r = os.path.realpath(r)
res.append(r)
for item in f:
res.append(os.path.join(r, item))
return _convType(retStr, res)
# all files including hidden files from specific directory recursively #
glob = SysMgr.getPkg("glob", False)
if glob:
"""
# sort option #
glob(value, key=os.path.getctime)
glob(value, key=os.path.getatime)
glob(value, key=os.path.getmtime)
glob(value, key=os.path.getsize)
"""
# check recursive path #
if "**" in value:
if sys.version_info >= (3, 11):
res = glob.glob(value, recursive=True, include_hidden=True)
elif sys.version_info >= (3, 5):
res = glob.glob(value, recursive=True)
else:
res = glob.glob(value)
else:
res = glob.glob(value)
if not res and isExit:
SysMgr.printErr("failed to find a file matching '%s'" % value)
sys.exit(-1)
return _convType(retStr, res)
elif warn:
if "*" in value:
SysMgr.printWarn(
"failed to handle * character in the path "
"because of no glob package",
True,
)
# str #
if retStr:
return value
# list #
else:
return [value]
@staticmethod
def convStr2Word(bstring):
try:
return struct.unpack("L", bstring)[0]
except SystemExit:
sys.exit(0)
except:
SysMgr.printErr("failed to convert string %s to word" % bstring)
return None
@staticmethod
def convOverlayPath(path, overlayfsList):
fileList = []
itemList = ["lowerdir", "upperdir"]
for pos, info in overlayfsList.items():
if not pos in path:
continue
for target in itemList:
for item in info[target]:
fullpath = item + path
if os.path.exists(fullpath):
fileList.append(fullpath)
# return recent path #
if fileList:
return fileList[-1]
else:
return path
@staticmethod
def convStr2Num(string, verb=True, onlyHex=False):
try:
if isinstance(string, (int, long)):
return string
elif not onlyHex and string.isdigit():
string = long(string)
else:
string = long(string, 16)
except SystemExit:
sys.exit(0)
except:
if verb:
SysMgr.printErr(
"failed to convert %s to number" % string, True
)
return None
return string
@staticmethod
def convNum(number, isFloat=False, floatDigit=1):
try:
if isFloat:
return format(round(float(number), floatDigit), ",")
else:
return format(long(number), ",")
except SystemExit:
sys.exit(0)
except:
return number
@staticmethod
def convCpuColor(value, string=None, size=1, align="right"):
if string is None:
string = value
if value >= SysMgr.cpuPerHighThreshold:
return UtilMgr.convColor(string, "RED", size, align)
elif value > 0:
return UtilMgr.convColor(string, "YELLOW", size, align)
else:
return str(string)
@staticmethod
def convColor(string, color="LIGHT", size=1, align="right", force=False):
# check skip condition #
if not color:
return str(string)
elif force and not SysMgr.isWindows:
pass
elif not SysMgr.colorEnable:
return str(string)
elif SysMgr.outPath or SysMgr.jsonEnable:
SysMgr.colorEnable = False
return str(string)
# direction #
if align == "right":
string = "{0:>{size}}".format(str(string), size=size)
else:
string = "{0:<{size}}".format(str(string), size=size)
# add color characters #
try:
return "%s%s%s" % (
ConfigMgr.COLOR_LIST[color],
string,
ConfigMgr.ENDC,
)
except SystemExit:
sys.exit(0)
except:
SysMgr.printWarn(
"failed to convert color for %s" % color, reason=True
)
return str(string)
@staticmethod
def convSize2UnitIgn(size, isInt=False, unit=None):
return str(size)
@staticmethod
def convSize2Unit(size, isInt=False, unit=None):
sizeKB = 1024
sizeMB = 1048576
sizeGB = 1073741824
sizeTB = 1099511627776
sizePB = 1125899906842624
sizeEB = 1152921504606846976
# sizeZB = 1180591620717411303424
# sizeYB = 120892581961462917470617
# convert to ABS value #
try:
sizeAbs = abs(size)
except SystemExit:
sys.exit(0)
except:
return "?"
if unit:
factor = 1 if isInt else 1.0
upperUnit = unit.upper()
if upperUnit == "K":
val = size / sizeKB * factor
elif upperUnit == "M":
val = size / sizeMB * factor
elif upperUnit == "G":
val = size / sizeGB * factor
elif upperUnit == "T":
val = size / sizeTB * factor
elif upperUnit == "P":
val = size / sizePB * factor
elif upperUnit == "E":
val = size / sizeEB * factor
else:
SysMgr.printErr("no support size unit '%s'" % unit)
sys.exit(-1)
if isInt:
num = UtilMgr.convNum(long(val))
else:
num = UtilMgr.convNum(round(float(val), 1), isFloat=True)
return "%s%s" % (num, upperUnit)
# Int type #
if isInt:
try:
if sizeAbs >= sizeEB:
return "%dE" % (size >> 60)
elif sizeAbs >= sizePB:
return "%dP" % (size >> 50)
elif sizeAbs >= sizeTB:
return "%dT" % (size >> 40)
elif sizeAbs >= sizeGB:
return "%dG" % (size >> 30)
elif sizeAbs >= sizeMB:
return "%dM" % (size >> 20)
elif sizeAbs >= sizeKB:
return "%dK" % (size >> 10)
else:
return "%d" % size
except SystemExit:
sys.exit(0)
except:
return "?"
# Float type #
else:
try:
if sizeAbs >= sizeEB:
return "%.1fE" % ((size >> 50) / 1024.0)
elif sizeAbs >= sizePB:
return "%.1fP" % ((size >> 40) / 1024.0)
elif sizeAbs >= sizeTB:
return "%.1fT" % ((size >> 30) / 1024.0)
elif sizeAbs >= sizeGB:
return "%.1fG" % ((size >> 20) / 1024.0)
elif sizeAbs >= sizeMB:
return "%.1fM" % ((size >> 10) / 1024.0)
elif sizeAbs >= sizeKB:
return "%.1fK" % (size / 1024.0)
else:
return "%d" % (size)
except SystemExit:
sys.exit(0)
except:
return "?"
@staticmethod
def convTime2Unit(sec):
sec = float(sec)
conv = UtilMgr.convNum
try:
if sec == long(sec):
return "%ssec" % conv(sec)
msSec = round(sec * 1000, 3)
msSecInt = long(msSec)
if msSec and msSec == msSecInt:
return "%sms" % msSecInt
usSec = round(sec * 1000000, 6)
usSecInt = long(usSec)
if usSec and usSec == usSecInt:
return "%sus" % usSecInt
nsSec = round(sec * 1000000000, 9)
nsSecInt = long(nsSec)
if nsSec and nsSec == nsSecInt:
return "%sns" % nsSecInt
return sec
except SystemExit:
sys.exit(0)
except:
return "?"
@staticmethod
def convTime2Sec(time):
# convert time to seconds #
try:
sec = 0
nums = time.strip().split(":")
if len(nums) == 3:
y = d = 0
times = nums
elif len(nums) == 4:
y = 0
d = int(nums[0].rstrip("d"))
times = nums[1:]
elif len(nums) == 5:
y = int(nums[0].rstrip("y"))
d = int(nums[0].rstrip("d"))
times = nums[1:]
else:
raise Exception()
# convert type #
h, m, s = list(map(int, times))
# convert items to seconds #
sec += s
sec += m * 60
sec += h * 3600
if d:
sec += d * 86400
if y:
sec += y * 31536000
except SystemExit:
sys.exit(0)
except:
pass
return sec
@staticmethod
def convTime(time, remainder=False):
try:
if not remainder:
raise Exception("integer")
remain = ".%02d" % long(time * 100 % 100)
except SystemExit:
sys.exit(0)
except:
remain = ""
# convert seconds to time #
try:
m, s = divmod(time, 60)
h, m = divmod(m, 60)
# hour #
if h >= 24:
d, h = divmod(h, 24)
# year #
if d >= 365:
y, d = divmod(d, 365)
d = "%dy:%dd:" % (y, d)
else:
d = "%dd:" % d
else:
d = ""
ctime = "%s%02d:%02d:%02d%s" % (d, h, m, s, remain)
except SystemExit:
sys.exit(0)
except:
ctime = "%s%02s:%02s:%02s%s" % ("", "?", "?", "?", remain)
return ctime.strip()
@staticmethod
def prepareForImageFile(logFile, itype="", outFile=None):
# build output file name #
if outFile:
outputFile = outFile
else:
# convert file object to string #
if hasattr(logFile, "name"):
logFile = logFile.name
if SysMgr.outPath:
outputFile = os.path.normpath(SysMgr.outPath)
else:
outputFile = os.path.normpath(logFile)
# convert output path #
if os.path.isdir(outputFile):
filename = os.path.basename(logFile)
filename = os.path.splitext(filename)[0]
name = "%s/%s" % (outputFile, filename)
else:
name = os.path.splitext(outputFile)[0]
outputFile = "%s_%s.%s" % (name, itype, SysMgr.drawFormat)
try:
# backup an exist image file #
if os.path.isfile(outputFile):
name, ext = os.path.splitext(outputFile)
oldPath = "%s_old%s" % (name, ext)
if os.path.isfile(oldPath):
os.remove(oldPath)
os.rename(outputFile, oldPath)
SysMgr.printInfo(
"renamed '%s' to '%s' for backup" % (outputFile, oldPath)
)
except SystemExit:
sys.exit(0)
except:
SysMgr.printErr(
"failed to backup '%s' to '%s'" % (outputFile, oldPath), True
)
return outputFile
@staticmethod
def convUnit2Time(data, isFloat=False):
if isFloat:
unit = float
else:
unit = long
if str(data).isdigit():
ret = unit(data)
elif data.upper().endswith("S"):
ret = unit(data[:-1])
elif data.upper().endswith("M"):
ret = unit(data[:-1]) * 60
elif data.upper().endswith("H"):
ret = unit(data[:-1]) * 60 * 60
elif data.upper().endswith("D"):
ret = unit(data[:-1]) * 60 * 60 * 24
elif data.upper().endswith("W"):
ret = unit(data[:-1]) * 60 * 60 * 24 * 7
else:
ret = 0
SysMgr.printErr("failed to convert '%s' to seconds" % data)
return ret
@staticmethod
def convUnit2Sec(data):
if str(data).isdigit():
ret = long(data)
elif data.upper().endswith("MS"):
ret = long(data[:-2]) / 1000.0
elif data.upper().endswith("US"):
ret = long(data[:-2]) / 1000000.0
elif data.upper().endswith("NS"):
ret = long(data[:-2]) / 1000000000.0
elif data.upper().endswith("PS"):
ret = long(data[:-2]) / 1000000000000.0
else:
ret = 0
SysMgr.printErr("failed to convert '%s' to seconds" % data)
return ret
@staticmethod
def convUnit2Size(value):
sizeKB = 1024
sizeMB = 1048576
sizeGB = 1073741824
sizeTB = 1099511627776
sizePB = 1125899906842624
sizeEB = 1152921504606846976
# sizeZB = 1180591620717411303424
# sizeYB = 120892581961462917470617
value = str(value)
# check type #
origValue = value
if value.startswith("-"):
value = value.lstrip("-")
factor = -1
else:
factor = 1
if str(value).isdigit():
return long(value) * factor
# convert unit character to capital #
value = value.upper()
try:
if value.endswith("K"):
return long(float(value[:-1]) * sizeKB) * factor
if value.endswith("KB"):
return long(float(value[:-2]) * sizeKB) * factor
if value.endswith("M"):
return long(float(value[:-1]) * sizeMB) * factor
if value.endswith("MB"):
return long(float(value[:-2]) * sizeMB) * factor
if value.endswith("G"):
return long(float(value[:-1]) * sizeGB) * factor
if value.endswith("GB"):
return long(float(value[:-2]) * sizeGB) * factor
if value.endswith("T"):
return long(float(value[:-1]) * sizeTB) * factor
if value.endswith("TB"):
return long(float(value[:-2]) * sizeTB) * factor
if value.endswith("P"):
return long(float(value[:-1]) * sizePB) * factor
if value.endswith("PB"):
return long(float(value[:-2]) * sizePB) * factor
if value.endswith("E"):
return long(float(value[:-1]) * sizeEB) * factor
if value.endswith("EB"):
return long(float(value[:-2]) * sizeEB) * factor
SysMgr.printErr("failed to convert '%s' to bytes" % origValue)
assert False
except SystemExit:
sys.exit(0)
except AssertionError:
raise Exception("wrong number unit")
except:
return origValue
@staticmethod
def saveStr2File(string, path):
# open the file #
try:
with open(path, "w") as fd:
fd.truncate()
fd.write(string)
except SystemExit:
sys.exit(0)
except:
SysMgr.printErr(
"failed to write JSON format data to %s" % path, True
)
sys.exit(-1)
@staticmethod
def writeJsonObject(jsonObj, fd=None, trunc=False, path=None):
if fd:
try:
if trunc:
fd.seek(0, 0)
fd.truncate()
except SystemExit:
sys.exit(0)
except:
pass
try:
fd.write(jsonObj)
fd.flush()
except SystemExit:
sys.exit(0)
except:
SysMgr.printWarn(
"failed to write JSON format data", reason=True
)
return
# check write option #
if trunc:
perm = "w"
else:
perm = "a"
# open the file #
try:
with open(path, perm) as fd:
fd.write(jsonObj)
except SystemExit:
sys.exit(0)
except:
SysMgr.printErr(
"failed to write JSON format data to %s" % path, True
)
sys.exit(-1)
@staticmethod
def saveObject2File(obj, path):
if not obj:
return False
pickle = SysMgr.getPicklePkg(False)
if not pickle:
return False
# compress by gzip #
if "COMPCACHE" in SysMgr.environList:
compressor = SysMgr.getPkg("gzip", False)
else:
compressor = False
# original object #
try:
if compressor:
with compressor.open(path, "wb") as fd:
pickle.dump(obj, fd, -1)
else:
with open(path, "wb") as fd:
pickle.dump(obj, fd, -1)
os.chmod(path, 0o777)
return True
except SystemExit:
sys.exit(0)
except:
SysMgr.printWarn(
"failed to save %s object to %s"
% (obj.__class__.__name__, path),
reason=True,
)
return False
@staticmethod
def loadObjectFromFile(path):
# check object exists #
if not os.path.isfile(path):
return None
# load pickle object #
pickle = SysMgr.getPicklePkg(False)
if not pickle:
return None
try:
# try to load compressed cache #
with SysMgr.getPkg("gzip", False).open(path, "rb") as fd:
return pickle.load(fd)
except SystemExit:
sys.exit(0)
except:
try:
with open(path, "rb") as fd:
return pickle.load(fd)
except SystemExit:
sys.exit(0)
except:
return None
@staticmethod
def printProgress(current=0, dest=0):
if not SysMgr.printEnable or dest == sys.maxsize:
return
# just output #
if not current and not dest:
if UtilMgr.progressCnt >= len(UtilMgr.progressChar) - 1:
UtilMgr.progressCnt = 0
else:
UtilMgr.progressCnt += 1
mod = UtilMgr.progressCnt
progressStr = ".... %s%s" % (UtilMgr.progressChar[mod], "\b" * 6)
else:
try:
div = round((current / float(dest)) * 100, 1)
except SystemExit:
sys.exit(0)
except:
div = 0
percent = long(div)
mod = percent & 3
progressStr = "%3d%% %s%s" % (
percent,
UtilMgr.progressChar[mod],
"\b" * 6,
)
# handle reentrant call exception #
try:
if progressStr == UtilMgr.progressStr:
return
UtilMgr.progressStr = progressStr
sys.stdout.write(progressStr)
sys.stdout.flush()
except SystemExit:
sys.exit(0)
except:
return
@staticmethod
def writeFlamegraph(path, samples, title, depth=20):
# flamegraph from https://github.com/rbspy/rbspy/tree/master/src/ui/flamegraph.rs #
# fixed font size: 12, bar height: 15 #
barHeight = 17
titleHeight = (title.count("
"""
)
attrCode = """
Guider Flame Graph
%s
Reset Zoom (ESC)
Search (F3)
""" % (
height,
"\r\n%s" % title if title else "",
titleHeight,
width,
)
# complete code for flamegraph #
finalCode = flameCode + attrCode + samples + "\n "
# write flamegraph to file #
try:
with open(path, "w") as fd:
fd.write(finalCode)
os.chmod(path, 0o777)
# get output size #
fsize = UtilMgr.getFileSizeStr(path)
SysMgr.printInfo(
"saved flamegraph into '%s'%s successfully" % (path, fsize)
)
except SystemExit:
sys.exit(0)
except:
SysMgr.printErr("failed to write flamegraph to %s" % path, True)
sys.exit(-1)
@staticmethod
def getFileSizeStr(path, string=True):
fsize = UtilMgr.getFileSize(path)
if fsize and fsize != "0":
fsize = " [%s]" % fsize
else:
fsize = ""
return fsize
@staticmethod
def getFileSize(path, string=True):
try:
fsize = long(os.path.getsize(path))
if string:
return UtilMgr.convSize2Unit(fsize)
else:
return fsize
except SystemExit:
sys.exit(0)
except:
if UtilMgr.isString(path) and os.path.exists(path):
SysMgr.printWarn("failed to get file size for '%s'" % path)
if string:
return "?"
else:
return 0
@staticmethod
def printFile(path):
try:
with open(path, "r") as fd:
for line in fd:
print(line.rstrip())
except SystemExit:
sys.exit(0)
except:
SysMgr.printErr("failed to print %s" % path, reason=True)
@staticmethod
def deleteProgress():
if not SysMgr.printEnable:
return
sys.stdout.write(" " * 6)
sys.stdout.write("\b" * 6)
# handle reentrant call exception #
try:
sys.stdout.flush()
except SystemExit:
sys.exit(0)
except:
return
@staticmethod
def which(cmd):
if not "PATH" in os.environ:
return None
pathList = []
for path in os.environ["PATH"].split(os.pathsep):
if os.path.exists(os.path.join(path, cmd)):
pathList.append(os.path.join(path, cmd))
if pathList:
return pathList
else:
return None
@staticmethod
def convDict2Str(dictObj, pretty=True, indent=2, ignore=False):
try:
if ignore:
jsonStr = SysMgr.getPkg("json").dumps(
dictObj,
indent=indent,
ensure_ascii=False,
default=lambda o: "",
)
else:
jsonStr = SysMgr.getPkg("json").dumps(
dictObj, indent=indent, ensure_ascii=False
)
if pretty:
return jsonStr
except SystemExit:
sys.exit(0)
except:
SysMgr.printWarn("failed to convert dict to string", reason=True)
"""
# for debugging #
SysMgr.printWarn(
"failed to convert %s to string" % [dictObj], reason=True)
"""
return None
# when encode flag is disabled, remove whitespace [\t\n\r\f\v] #
if not SysMgr.encodeEnable:
jsonStr = re.sub("\s", "", jsonStr) + "\n"
return jsonStr
@staticmethod
def convUlong2Long(retval):
retval = retval & 0xFFFFFFFFFFFFFFFF
if retval & 0x8000000000000000:
retval = retval - 0x10000000000000000
return retval
@staticmethod
def convStr2Dict(strObj, verb=False):
try:
return SysMgr.getPkg("json").loads(strObj)
except SystemExit:
sys.exit(0)
except:
try:
strObj = strObj.replace("'", '"')
return SysMgr.getPkg("json").loads(strObj)
except SystemExit:
sys.exit(0)
except:
SysMgr.printWarn(
"failed to convert %s to dict" % [strObj],
always=verb,
reason=True,
)
return None
class NetworkMgr(object):
"""Manager for remote communication"""
# define valid request list #
REQUEST_LIST = {
"BROADCAST": None,
"CLEAR": None,
"DOWNLOAD": None,
"JOBS": None,
"LIST": None,
"NEW": None,
"NOTIFY": None,
"PING": None,
"RESTART": None,
"RUN": None,
"UPLOAD": None,
"UPSTREAM": None,
}
def __init__(
self,
mode,
ip,
port,
tcp=False,
uds=False,
netlink=False,
blocking=True,
anyPort=False,
bind=True,
reuse=True,
):
self.mode = mode
self.ip = None
self.port = None
self.socket = None
self.request = None
self.status = None
self.ignore = 0
self.fileno = -1
self.time = None
self.sendSize = 32767
self.recvSize = 32767
self.tcp = tcp
self.netlink = netlink
self.connected = False
# get socket object #
socket = SysMgr.getPkg("socket")
try:
from socket import (
socket,
AF_INET,
SOCK_DGRAM,
SOCK_STREAM,
SOL_SOCKET,
SO_REUSEADDR,
SO_SNDBUF,
SO_RCVBUF,
SOL_TCP,
SO_RCVTIMEO,
SO_SNDTIMEO,
SOCK_RAW,
)
except:
SysMgr.printWarn("failed to import socket", True, reason=True)
return None
try:
# set socket type #
if tcp:
self.socket = socket(AF_INET, SOCK_STREAM)
elif uds:
from socket import AF_UNIX # pylint: disable=no-name-in-module
self.socket = socket(AF_UNIX, SOCK_STREAM)
elif netlink:
try:
from socket import (
AF_NETLINK,
) # pylint: disable=no-name-in-module
self.socket = socket(
AF_NETLINK,
SOCK_RAW,
ConfigMgr.NETLINK_TYPE["NETLINK_GENERIC"],
)
except:
SysMgr.printWarn(
"failed to create NETLINK socket", True, reason=True
)
return None
else:
self.socket = socket(AF_INET, SOCK_DGRAM)
self.fileno = self.socket.fileno()
# increase socket buffer size to 1MB #
self.socket.setsockopt(SOL_SOCKET, SO_SNDBUF, 1 << 20)
self.socket.setsockopt(SOL_SOCKET, SO_RCVBUF, 1 << 20)
# get buffer size #
self.sendSize = self.socket.getsockopt(SOL_SOCKET, SO_SNDBUF)
self.recvSize = self.socket.getsockopt(SOL_SOCKET, SO_RCVBUF)
# set REUSEADDR flag #
if reuse:
self.socket.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
# set REUSEPORT #
"""
from socket import SO_REUSEPORT
self.socket.setsockopt(SOL_SOCKET, SO_REUSEPORT, 0)
"""
# set NODELAY #
"""
self.setNoDelay()
"""
# set SENDTIMEOUT #
"""
sec = 1
usec = 0
timeval = struct.pack('ll', sec, usec)
self.socket.setsockopt(SOL_SOCKET, SO_SNDTIMEO, timeval)
"""
if uds:
return None
# convert IP #
if ip == "*":
ip = "0.0.0.0"
# set IP & PORT #
self.ip = ip
self.port = port
if mode == "server":
# IP #
if ip is None:
self.ip = "0.0.0.0"
# PORT #
if anyPort:
self.port = 0
elif port is None:
self.port = SysMgr.defaultServPort
# bind #
if bind:
try:
self.socket.bind((self.ip, self.port))
except OSError as e:
if e.errno == errno.EADDRINUSE:
self.port = 0
self.socket.bind((self.ip, self.port))
else:
raise e
except SystemExit:
sys.exit(0)
except:
self.socket.bind((self.ip, self.port))
# get bind port #
self.port = self.socket.getsockname()[1]
if not blocking:
self.socket.setblocking(0)
except:
err = SysMgr.getErrMsg()
if err.startswith("13") and not SysMgr.isRoot() and port < 1024:
feedback = ", use port bigger than 1024"
else:
feedback = ""
# check mode to print error message #
if (
SysMgr.warnEnable
or SysMgr.checkMode("server")
or SysMgr.checkMode("cli")
):
SysMgr.printErr(
(
"failed to create a socket for %s:%s as server "
"because %s%s"
)
% (self.ip, self.port, err, feedback)
)
"""
if error "99 Cannot assign requested address" occurs:
add "net.ipv4.ip_nonlocal_bind = 1" in /etc/sysctl.conf
execute sysctl -p /etc/sysctl.conf
"""
self.ip = None
self.port = None
return None
def __str__(self):
return "%s object at %x, IP: %s, PORT: %s" % (
self.__class__,
id(self),
self.ip,
self.port,
)
def listen(self, nrQueue=5):
return self.socket.listen(nrQueue)
def accept(self):
return self.socket.accept()
def bind(self, ip, port):
return self.socket.bind((ip, port))
def write(self, message):
return self.send(message, write=True)
def close(self):
if self.socket:
ret = self.socket.close()
else:
ret = False
self.socket = None
return ret
def flush(self):
pass
def timeout(self, sec=3):
if "TIMEOUT" in SysMgr.environList:
sec = UtilMgr.getEnvironNum("TIMEOUT")
self.socket.settimeout(sec)
@staticmethod
def sendFile(sock, ip, port, src, des):
# verify path #
target = src
sdir, name = UtilMgr.getPath(target)
# get file list #
targetList = UtilMgr.getFiles(sdir, [name])
if not targetList:
SysMgr.printWarn("failed to find %s to transfer" % target, True)
return False
for target in targetList:
target = SysMgr.convFullPath(target)
SysMgr.printInfo(
"start uploading %s[%s] to %s:%s... "
% (target, UtilMgr.getFileSize(target), sock.ip, sock.port),
suffix=False,
)
# send file info #
totalSize = os.stat(target).st_size
fileInfo = "%s#%s" % (target, totalSize)
sock.send(UtilMgr.encodeStr(fileInfo))
# read for ACK #
while 1:
ret = sock.recv(3)
if ret is None:
continue
elif ret is False:
raise Exception("no response")
else:
break
# send a file #
with open(target, "rb") as fd:
buf = fd.read(sock.sendSize)
curSize = 0
while buf:
# send a chunk #
sock.send(buf)
curSize += len(buf)
# read for ACK #
while 1:
ret = sock.recv(3)
if ret is None:
continue
elif ret is False:
raise Exception("no response")
else:
break
# read a chunk #
buf = fd.read(sock.sendSize)
# read for ACK #
while 1:
ret = sock.recv(3)
if ret is None:
continue
elif ret is False:
raise Exception("no response")
else:
break
SysMgr.printInfo(
"uploaded %s[%s] to %s:%s successfully"
% (target, UtilMgr.getFileSize(target), sock.ip, sock.port)
)
return True
@staticmethod
def recvData(sockObj, ip, port=0):
connMan = NetworkMgr("server", ip, port, tcp=True, bind=True)
if not connMan.ip:
return
# send connection info #
try:
sockObj.send(("%s:%s" % (connMan.ip, connMan.port)).encode())
except SystemExit:
sys.exit(0)
except:
SysMgr.printErr(
"failed to send connection info to %s:%s"
% (sockObj.ip, sockObj.port),
True,
)
return
# listen #
try:
connMan.listen()
connMan.timeout()
except SystemExit:
sys.exit(0)
except:
SysMgr.printErr("failed to listen to prepare for connection", True)
sys.exit(-1)
# accept #
try:
sock, addr = connMan.accept()
except SystemExit:
sys.exit(0)
except IOError as err:
if err.errno != errno.EINTR:
SysMgr.printWarn(
"failed to accept the connection request", reason=True
)
return
except SysMgr.getPkg("socket").timeout:
return
except:
SysMgr.printWarn(
"failed to accept the connection request", reason=True
)
return
SysMgr.printInfo(
"connected to the new client (%s:%s)" % (addr[0], addr[1])
)
try:
# get payload size #
size = sock.recv(SysMgr.PAGESIZE)
size = long(size.decode())
# send ACK #
sock.send("ACK".encode())
except SystemExit:
sys.exit(0)
except:
SysMgr.printErr(
"failed to get payload size from %s:%s" % (addr[0], addr[1]),
True,
)
return
# receive data #
try:
buf = b""
while 1:
data = sock.recv(SysMgr.PAGESIZE)
if data:
buf += data
else:
break
except SystemExit:
sys.exit(0)
except:
SysMgr.printErr(
"failed to receive data from %s:%s" % (addr[0], addr[1]), True
)
return
return buf
@staticmethod
def recvFile(sock, ip, port, src, des):
# get select object #
selectObj = SysMgr.getPkg("select")
while 1:
curSize = 0
totalSize = None
# receive file info #
while 1:
fileInfo = sock.recv(sock.recvSize)
if not fileInfo:
continue
# check termination condition #
name, size = fileInfo.decode().split("#", 1)
if name == "@DONE":
return True
elif not size:
continue
# send ACK for file info #
totalSize = long(size)
sock.send("ACK".encode())
break
# set destination path #
fname = os.path.basename(name)
if des:
if os.path.isdir(des):
target = os.path.join(des, fname)
else:
target = des
else:
target = name
# make dirs #
dirPos = target.rfind("/")
if dirPos >= 0 and not os.path.isdir(target[:dirPos]):
os.makedirs(target[:dirPos])
# convert path #
target = SysMgr.convFullPath(target)
if os.path.isdir(target):
target = os.path.join(target, fname)
SysMgr.printInfo(
"start downloading %s[%s]@%s:%s to %s..."
% (name, UtilMgr.convSize2Unit(totalSize), ip, port, target),
suffix=False,
)
# receive a file #
with open(target, "wb") as fd:
# change permission #
os.chmod(target, 0o777)
sent = 0
while 1:
selectObj.select([sock.socket], [], [], 3)
# receive a chunk #
buf = sock.recv(sock.recvSize)
if not buf:
break
# update stat and write a chunk to file #
curSize += len(buf)
sent += len(buf)
fd.write(buf)
# check received size #
if curSize >= totalSize:
sock.send("ACK".encode())
break
# send ACK for a complete chunk #
if sent == sock.recvSize:
sock.send("ACK".encode())
sent = 0
# print progress #
UtilMgr.printProgress(curSize, totalSize)
# remove progress #
UtilMgr.deleteProgress()
# check received size #
if curSize < totalSize:
raise Exception("broken connection")
SysMgr.printInfo(
"downloaded %s[%s]@%s:%s to %s successfully\n"
% (target, UtilMgr.getFileSize(target), ip, port, name),
suffix=False,
)
# send ACK #
sock.send("ACK".encode())
return True
def customBind(self):
# get bind info #
ipList = portList = []
if "CLIIP" in SysMgr.environList:
ipList = SysMgr.environList["CLIIP"]
if "CLIPORT" in SysMgr.environList:
portList = SysMgr.environList["CLIPORT"]
# check bind address #
if not ipList and not portList:
return True
# set default IP #
if not ipList:
ipList = ["0"]
# convert PORT list #
if portList:
newPortList = []
for item in portList:
if not "-" in item:
newPortList.append(long(item))
continue
try:
start, end = item.split("-")
if end == "":
end = 65535
for idx in xrange(long(start), long(end) + 1):
newPortList.append(idx)
except SystemExit:
sys.exit(0)
except:
SysMgr.printErr("failed to bind client socket", True)
return False
portList = list(set(newPortList))
else:
portList = [0]
# disable REUSEADDR flag #
socket = SysMgr.getPkg("socket")
self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 0)
# bind #
isBound = False
for ip in ipList:
for port in portList:
try:
self.bind(ip, port)
SysMgr.printWarn(
"succeed to bind client socket to %s:%s" % (ip, port)
)
isBound = True
break
except SystemExit:
sys.exit(0)
except:
SysMgr.printWarn(
"failed to bind client socket to %s:%s" % (ip, port),
reason=True,
)
# check result #
if isBound:
return True
else:
SysMgr.printErr("failed to bind local address for client socket")
return False
def connect(self, addr=None):
if addr is None:
addr = (self.ip, self.port)
# bind to specific address #
if not self.customBind():
raise Exception("bind failure")
self.socket.connect(addr)
self.connected = True
def handleServerRequest(self, req, onlySocket=False):
def _onDownload(req):
# parse path #
reqList = req.split("|", 1)[1]
path = UtilMgr.cleanItem(reqList.split("@"), False)
if len(path) == 2:
origPath, desPath = path
if origPath and not desPath:
origPath = desPath
else:
origPath = path[0]
desPath = None
res = False
# receive file #
try:
res = NetworkMgr.recvFile(
self, self.ip, self.port, origPath, desPath
)
except:
res = False
SysMgr.printErr(
"failed to download %s from %s in %s:%s"
% (origPath, desPath, self.ip, self.port),
True,
)
finally:
try:
self.close()
except:
pass
finally:
return res
def _onUpstream(req):
pass
def _onNotify(req):
return True
def _onUpload(req):
# parse path #
reqList = req.split("|", 1)[1]
path = UtilMgr.cleanItem(reqList.split("@"), False)
if len(path) == 2:
origPath, targetPath = path
if origPath and not targetPath:
origPath = targetPath
else:
origPath = targetPath = path[0]
res = False
# transfer file #
try:
res = NetworkMgr.sendFile(
self, self.ip, self.port, origPath, targetPath
)
except:
res = False
SysMgr.printErr(
"failed to upload %s to %s in %s:%s"
% (origPath, targetPath, self.ip, self.port),
True,
)
finally:
try:
self.send("@DONE#0".encode())
self.close()
except:
pass
finally:
return res
def _onList(req):
SysMgr.printInfo(UtilMgr.lstrip(req, "LIST:"))
return True
def _onClear(req):
SysMgr.printInfo(UtilMgr.lstrip(req, "CLEAR:"))
return True
def _onJobs(req):
SysMgr.printInfo(UtilMgr.lstrip(req, "JOBS:"))
return True
def _onRun(req, onlySocket):
# parse command #
command = req.split("|", 1)[1]
# parse addr #
addr = "%s:%s" % (self.ip, self.port)
if not onlySocket:
SysMgr.printInfo("executed '%s' from %s\n" % (command, addr))
# return just the connected socket #
if onlySocket:
return self
# get select object #
selectObj = SysMgr.getPkg("select")
# set print flag #
printFlag = SysMgr.getPrintFlag()
if printFlag:
print(oneLine)
# run mainloop #
isPrint = False
while 1:
try:
selectObj.select([self.socket], [], [])
# receive packet #
output = self.getData()
if not output:
break
if printFlag:
print(output[:-1])
isPrint = True
except:
break
# print output from server #
if not isPrint:
print("no response")
if printFlag:
print(oneLine)
# close connection #
try:
self.close()
except:
pass
# get select object to check reply #
SysMgr.getPkg("select")
# unmarshalling #
if type(req) is tuple:
try:
req = req[0].decode()
except:
req = req[0]
# check request #
if not req:
return
# handle request #
reqUpper = req.upper()
if reqUpper.startswith("DOWNLOAD"):
return _onDownload(req)
elif reqUpper.startswith("UPLOAD"):
return _onUpload(req)
elif reqUpper.startswith("RUN"):
return _onRun(req, onlySocket)
elif reqUpper.startswith("LIST:"):
return _onList(req)
elif reqUpper.startswith("CLEAR"):
return _onClear(req)
elif reqUpper.startswith("JOBS"):
return _onJobs(req)
elif reqUpper.startswith("NOTIFY"):
return _onNotify(req)
elif reqUpper.startswith("ERROR"):
err = req.split("|", 1)[1]
errToken = err.find("':")
errMsg = "%s' from %s" % (err[:errToken], err[errToken + 2 :])
SysMgr.printErr(errMsg)
else:
SysMgr.printErr("failed to recognize '%s' request" % req)
elif not req:
SysMgr.printErr("no response from server")
else:
SysMgr.printErr("received wrong reply '%s'" % req)
def send(self, message, write=False):
if None in (self.ip, self.port):
SysMgr.printWarn(
"failed to use IP address for client because it is not set"
)
return False
elif not self.socket:
SysMgr.printErr(
"failed to use socket for client because it is not set"
)
return False
# encode message #
if UtilMgr.isString(message):
message = UtilMgr.encodeStr(message)
# convert list to bytes #
if type(message) is list:
if not message:
message = "".encode()
elif message[0][-1] == "\n":
message = "".join(message).encode()
else:
message = "\n".join(message).encode()
try:
# send data #
if self.tcp or self.netlink:
ret = self.socket.send(message)
elif not write and SysMgr.localServObj:
ret = SysMgr.localServObj.socket.sendto(
message, (self.ip, self.port)
)
else:
ret = self.socket.sendto(message, (self.ip, self.port))
# check result #
if ret < 0:
raise Exception("send error")
elif self.status != "ALWAYS":
self.status = "SENT"
return True
except SystemExit:
sys.exit(0)
except:
SysMgr.printErr(
"failed to send data to %s:%d as server"
% (self.ip, self.port),
True,
)
return False
def sendto(self, message, ip, port):
if not ip or not port:
SysMgr.printWarn(
"failed to use IP address for client because it is not set"
)
return False
elif not self.socket:
SysMgr.printErr(
"failed to use socket for client because it is not set"
)
return False
# encode message #
if UtilMgr.isString(message):
message = UtilMgr.encodeStr(message)
try:
self.socket.sendto(message, (ip, port))
return True
except SystemExit:
sys.exit(0)
except:
SysMgr.printErr(
"failed to send data to %s:%d as client"
% (self.ip, self.port),
True,
)
return False
def recv(self, size=0):
if None in (self.ip, self.port):
SysMgr.printWarn(
"failed to use IP address for server because it is not set"
)
return False
elif not self.socket:
SysMgr.printErr(
"failed to use socket for client because it is not set"
)
return False
# set recv size #
if size == 0:
size = self.recvSize
try:
return self.socket.recv(size)
except SystemExit:
sys.exit(0)
except:
SysMgr.printWarn(
"failed to receive data from %s:%d as client"
% (self.ip, self.port),
reason=True,
)
return False
def getData(self, noTimeout=True):
try:
data = b""
# receive and composite packets #
while 1:
output = self.recvfrom(noTimeout=noTimeout)
# handle error #
if not output:
continue
# handle timeout #
if not noTimeout and (not output[0] and not output[1]):
if data:
return data
else:
return None
# get only data #
output = output[0]
# composite packets #
data += output
if not output:
break
# decode data #
try:
output = output.decode()
except:
pass
if len(output) < self.recvSize and output[-1] == "\n":
break
except SystemExit:
sys.exit(0)
except:
SysMgr.printErr(
"failed to get data from %s:%d as client"
% (self.ip, self.port),
True,
)
return None
# decode data #
try:
retstr = data.decode()
return retstr
except:
return data
def setNoDelay(self):
from socket import socket, SOL_TCP, TCP_NODELAY
# set NODELAY for NAGLE #
self.socket.setsockopt(SOL_TCP, TCP_NODELAY, 1)
def recvfrom(self, size=0, noTimeout=False, verb=True):
if None in (self.ip, self.port):
SysMgr.printWarn(
"failed to use IP address for server because it is not set"
)
return False
elif not self.socket:
SysMgr.printErr(
"failed to use socket for client because it is not set"
)
return False
# get socket object #
socket = SysMgr.getPkg("socket", False)
if not socket:
return
# set recv size #
if size == 0:
size = self.recvSize
while 1:
try:
message, address = self.socket.recvfrom(size)
return (message, address)
except socket.timeout:
if noTimeout:
continue
SysMgr.printWarn(
(
"failed to receive data from %s:%d as client"
"because of %s"
)
% (self.ip, self.port, "timeout")
)
return None
except KeyboardInterrupt:
sys.exit(0)
except SystemExit:
sys.exit(0)
except:
if verb:
SysMgr.printWarn(
"failed to receive data from %s:%d as client"
% (self.ip, self.port),
reason=True,
)
return None
@staticmethod
def getDataType(data):
if not data:
return "None"
data = data.lstrip()
if data.startswith("{"):
return "JSON"
elif (
"[INFO" in data[:10]
or "[ERROR" in data[:10]
or "[WARN" in data[:10]
or "[STEP" in data[:10]
):
return "LOG"
else:
return "CONSOLE"
@staticmethod
def requestCmd(connObj, cmd):
if not connObj:
return
# send request to server #
connObj.send(cmd)
# receive reply from server #
reply = connObj.recvfrom()
# handle reply from server #
try:
connObj.handleServerRequest(reply)
except:
return
@staticmethod
def requestPing(addr=None, verb=True, cmd=None):
if cmd:
cmd = cmd.upper()
cmd = "%s:%s" % (cmd, cmd)
else:
cmd = "PING:PING"
return NetworkMgr.execRemoteCmd(cmd, addr=addr, verb=verb)
@staticmethod
def getCmdPipe(connObj, cmd):
if not cmd:
return None
# add command prefix #
reqCmd = cmd.split(":", 1)[0].upper()
if reqCmd in NetworkMgr.REQUEST_LIST:
pass
elif not cmd.startswith("run:"):
cmd = "run:%s" % cmd
# send request to server #
connObj.send(cmd)
# receive reply from server #
reply = connObj.recvfrom()
try:
if not reply:
raise Exception()
msg = reply[0].decode()
if not msg:
pass
elif msg == "PONG":
return True
elif msg == "NO_SERV_NODE":
SysMgr.printErr(
"no service node to %s:%s" % (connObj.ip, connObj.port)
)
return True
elif msg.startswith("MSG:"):
# print message in the packet #
SysMgr.printInfo(UtilMgr.lstrip(msg, "MSG:"))
# send ACK to prevent receiving two packegs at once #
connObj.send("ACK")
# wait for a request again #
reply = connObj.recvfrom()
elif msg.startswith("LIST:"):
reply = (msg,)
elif msg.startswith("NOTIFY:"):
return True
except:
pass
# handle reply from server #
try:
return connObj.handleServerRequest(reply, onlySocket=True)
except:
return None
@staticmethod
def execRemoteCmd(command, addr=None, verb=True):
# get new connection #
connObj = NetworkMgr.getServerConn(addr, verb)
if not connObj:
return None
# launch remote command #
pipe = NetworkMgr.getCmdPipe(connObj, command)
return pipe
@staticmethod
def getServerConn(addr=None, verb=True):
def _printErr():
SysMgr.printErr("no running server or wrong server address")
# set server address in local #
if addr:
# classify IP and PORT #
service, ip, port = NetworkMgr.parseAddr(addr)
if service == ip == port == None:
_printErr()
return None
else:
NetworkMgr.setRemoteServer("%s:%s" % (ip, port), tcp=True)
elif SysMgr.isLinux and not SysMgr.remoteServObj:
try:
addr = SysMgr.getProcNetAddrs(__module__)
except:
addr = None
if not addr:
return None
# classify IP and PORT #
service, ip, port = NetworkMgr.parseAddr(addr)
if service == ip == port == None:
_printErr()
return None
else:
NetworkMgr.setRemoteServer(addr, tcp=True)
# set server address again #
elif SysMgr.remoteServObj:
servObj = SysMgr.remoteServObj
ip = servObj.ip
port = servObj.port
NetworkMgr.setRemoteServer("%s:%s" % (ip, port), tcp=True)
# check server address #
if not SysMgr.remoteServObj:
_printErr()
return None
# bind local socket for UDP #
try:
if not SysMgr.remoteServObj.tcp and SysMgr.localServObj:
lip = SysMgr.localServObj.ip
lport = SysMgr.localServObj.port
SysMgr.remoteServObj.socket.bind((lip, lport))
except:
SysMgr.printErr(
"failed to bind socket to %s:%s for connection" % (lip, lport),
True,
)
# do connect to server #
try:
connObj = SysMgr.remoteServObj
if not "NOTIMEOUT" in SysMgr.environList:
connObj.timeout()
# set immediately exit flag to prevent hang on connect #
origFlag = SysMgr.exitFlag
SysMgr.exitFlag = True
# connect with handling CLOSE_WAIT #
while 1:
try:
connObj.connect()
break
except SystemExit:
sys.exit(0)
except:
SysMgr.printWarn(
"failed to connect to %s:%s" % (ip, port),
reason=True,
always=verb,
)
# handle error #
_, err, to = sys.exc_info()
if err.args and err.args[0] == 99:
time.sleep(0.1)
continue
else:
raise Exception(err.args[0])
finally:
SysMgr.exitFlag = origFlag
return connObj
except SystemExit:
sys.exit(0)
except:
if verb:
SysMgr.printErr("failed to set socket for connection", True)
return None
@staticmethod
def parseAddr(value):
service = None
ip = None
port = None
if not UtilMgr.isString(value):
return (service, ip, port)
# get request and address #
cmdList = value.split("@")
if len(cmdList) >= 2:
service = cmdList[0]
addr = cmdList[1]
else:
addr = value
# get IP and PORT #
addrList = addr.split(":")
if len(addrList) >= 2:
try:
if addrList[0]:
ip = addrList[0]
if addrList[1]:
port = long(addrList[1])
except:
pass
else:
try:
if "." in addrList[0]:
ip = addrList[0]
else:
port = long(addrList[0])
except:
pass
return (service, ip, port)
@staticmethod
def setRemoteServer(value, tcp=False, verb=True):
# receive mode #
if not value:
SysMgr.remoteServObj = "NONE"
return
# request mode #
service, ip, port = NetworkMgr.parseAddr(value)
# set PRINT as default #
if not service:
service = "PRINT"
if not ip:
ip = NetworkMgr.getPublicIp()
if port is None:
port = SysMgr.defaultServPort
# check server addresses #
if (
SysMgr.localServObj
and SysMgr.localServObj.ip == ip
and SysMgr.localServObj.port == port
):
SysMgr.printErr(
(
"wrong value for remote connection, "
"local address and remote address are same "
"(%s:%s)"
)
% (ip, port)
)
sys.exit(-1)
# check request #
if not ip or not port or not SysMgr.isValidRequest(service):
reqList = ""
for req in TaskAnalyzer.requestType:
reqList += req + "|"
SysMgr.printErr(
(
"wrong input address, "
"input [%s]@IP:PORT as remote address"
)
% reqList[:-1]
)
sys.exit(-1)
# create a socket #
networkObject = NetworkMgr("client", ip, port, tcp=tcp)
if not networkObject.ip:
sys.exit(-1)
else:
networkObject.request = service
SysMgr.remoteServObj = networkObject
# set protocol #
if tcp:
proto = "TCP"
else:
proto = "UDP"
if verb:
SysMgr.printInfo(
"use %s:%d(%s) as remote address" % (ip, port, proto)
)
return SysMgr.remoteServObj
@staticmethod
def setRemoteNetwork(service, ip, port):
# set default service #
if not service:
service = "PRINT"
errMsg = (
"wrong value for remote server, "
"input in the format [%s]@IP:PORT"
) % "|".join(TaskAnalyzer.requestType)
if not ip or not SysMgr.isValidRequest(service):
SysMgr.printErr(errMsg)
sys.exit(-1)
if port is None:
port = SysMgr.defaultServPort
# create a new object #
netObj = NetworkMgr("client", ip, port)
if not netObj.ip:
sys.exit(-1)
else:
netObj.status = "ALWAYS"
netObj.request = service
naddr = "%s:%s" % (ip, str(port))
if service == "PRINT":
SysMgr.addrListForPrint[naddr] = netObj
elif service.startswith("REPORT_"):
SysMgr.reportEnable = True
SysMgr.addrListForReport[naddr] = netObj
else:
SysMgr.printErr(errMsg)
SysMgr.printInfo(
"use %s:%d as remote address to request %s" % (ip, port, service)
)
@staticmethod
def setServerNetwork(
ip,
port,
force=False,
blocking=False,
tcp=False,
anyPort=False,
reuse=True,
weakPort=False,
verb=False,
):
if SysMgr.localServObj and not force:
SysMgr.printWarn(
"ignored to set server network because its already set", verb
)
return
# get internet available IP first #
if not ip:
ip = NetworkMgr.getPublicIp()
# set default port #
if port is None:
if SysMgr.checkMode("cli"):
port = SysMgr.defaultCliPort
else:
port = SysMgr.defaultServPort
# print available IP list #
try:
iplist = sorted(NetworkMgr.getUsingIps())
if iplist:
SysMgr.printWarn(
"available IP list [ %s ]" % ", ".join(iplist), verb
)
except:
pass
# check server setting #
localObj = SysMgr.localServObj
if (
localObj
and localObj.socket
and localObj.ip == ip
and localObj.port == port
):
if blocking:
localObj.socket.setblocking(1)
else:
localObj.socket.setblocking(0)
return
# create a new server setting #
networkObject = NetworkMgr(
"server",
ip,
port,
tcp=tcp,
blocking=blocking,
anyPort=anyPort,
reuse=reuse,
)
if not networkObject.ip and weakPort:
networkObject = NetworkMgr(
"server",
ip,
port,
tcp=tcp,
blocking=blocking,
anyPort=True,
reuse=reuse,
)
if not networkObject.ip:
SysMgr.printWarn("failed to set server IP", verb)
return
# set protocol #
if tcp:
proto = "TCP"
else:
proto = "UDP"
localObj = SysMgr.localServObj = networkObject
if not SysMgr.masterPid:
SysMgr.printInfo(
"use %s:%d(%s) as local address"
% (localObj.ip, localObj.port, proto)
)
return networkObject
@staticmethod
def prepareServerConn(cliAddr, servAddr):
# set local address #
if not cliAddr:
NetworkMgr.setServerNetwork(None, None, anyPort=True)
else:
service, ip, port = NetworkMgr.parseAddr(cliAddr)
NetworkMgr.setServerNetwork(ip, port)
# set remote address #
if servAddr:
NetworkMgr.setRemoteServer(servAddr)
# set client address #
if SysMgr.localServObj:
cliIp = SysMgr.localServObj.ip
cliPort = SysMgr.localServObj.port
else:
cliIp = None
cliPort = None
# set server address #
if SysMgr.remoteServObj.ip:
servIp = SysMgr.remoteServObj.ip
servPort = SysMgr.remoteServObj.port
else:
servIp = None
servPort = None
return (cliIp, cliPort), (servIp, servPort)
@staticmethod
def getDevByIp(ip):
# get device data #
data = SysMgr.getNetDevData()
if not data:
return
# create a new socket #
try:
fcntl = SysMgr.getPkg("fcntl", False)
socket = SysMgr.getPkg("socket", False)
sobj = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
except SystemExit:
sys.exit(0)
except:
return
# scan IP device and address #
for line in data:
try:
dev, stats = line.split(":")
dev = dev.strip()
res = fcntl.ioctl(
sobj.fileno(),
0x8915, # SIOCGIFADDR
struct.pack("256s", dev[:15].encode("utf-8")),
)
ipaddr = socket.inet_ntoa(res[20:24])
if ipaddr == ip:
return dev
except SystemExit:
sys.exit(0)
except:
pass
@staticmethod
def getMainMacAddr():
dirPath = "/sys/class/net"
try:
devices = os.listdir(dirPath)
except SystemExit:
sys.exit(0)
except:
SysMgr.printOpenErr(dirPath)
return
# return main IP and device #
try:
ip = NetworkMgr.getPublicIp()
if ip:
dev = NetworkMgr.getDevByIp(ip)
if dev:
return (dev, ip)
except SystemExit:
sys.exit(0)
except:
pass
for dev in devices:
# skip virtual device #
if dev == "lo" or dev.startswith("docker"):
continue
target = "%s/%s/address" % (dirPath, dev)
try:
with open(target, "r") as fd:
addr = fd.readline()[:-1]
return (dev, addr)
except SystemExit:
sys.exit(0)
except:
SysMgr.printOpenErr(target)
return ("None", "None")
@staticmethod
def getUsingIps():
if not SysMgr.isLinux:
return
connPaths = [
"%s/net/udp" % SysMgr.procPath,
"%s/net/tcp" % SysMgr.procPath,
]
effectiveList = {}
cacheList = {}
for path in connPaths:
try:
with open(path, "r") as fd:
ipList = fd.read().split("\n")
# remove title #
ipList.pop(0)
for line in ipList:
if not line:
continue
items = line.split(None, 2)
addr = items[1].split(":")[0]
if addr in cacheList:
continue
cacheList[addr] = None
ip = SysMgr.convCIDR(addr)
effectiveList[ip] = None
except SystemExit:
sys.exit(0)
except:
SysMgr.printOpenWarn(path)
return list(effectiveList)
@staticmethod
def getGateways():
gateways = {}
ips = NetworkMgr.getRoutedIps()
for item in ips:
try:
ip = item[1]
if ip in ("0.0.0.0", "127.0.0.1") or not ip.endswith(".1"):
continue
gw = "%s.1" % ip[: ip.rfind(".")]
gateways[gw] = None
except SystemExit:
sys.exit(0)
except:
pass
return list(gateways)
@staticmethod
def getMainIp():
ipList = NetworkMgr.getUsingIps()
# remove IP for all IPv4 addresses #
try:
ipList.remove("0.0.0.0")
except SystemExit:
sys.exit(0)
except:
pass
# return main IP #
if not ipList:
return None
elif "127.0.0.1" in ipList:
return "127.0.0.1"
else:
return list(sorted(ipList, reverse=True))[0]
@staticmethod
def getRoutedIps():
effectiveList = []
routePath = "%s/net/route" % SysMgr.procPath
try:
with open(routePath, "r") as fd:
ipList = fd.readlines()
# remove title #
ipList.pop(0)
for line in ipList:
items = line.split()
effectiveList.append([items[0], SysMgr.convCIDR(items[1])])
return effectiveList
except SystemExit:
sys.exit(0)
except:
SysMgr.printOpenWarn(routePath)
return effectiveList
@staticmethod
def getHostName():
try:
return SysMgr.getPkg("socket").gethostname()
except:
return None
@staticmethod
def getPublicIp(force=False):
if SysMgr.ipAddr and not force:
return SysMgr.ipAddr
# get socket object #
socket = SysMgr.getPkg("socket", False)
if not socket:
return
from socket import socket, AF_INET, SOCK_DGRAM, SOCK_STREAM
ret = None
try:
s = socket(AF_INET, SOCK_STREAM)
s.settimeout(0.3)
# connect to google public IP #
s.connect(("8.8.8.8", 53))
ret = s.getsockname()[0]
except SystemExit:
sys.exit(0)
except:
SysMgr.printWarn("failed to get public IP address")
if not ret:
ret = NetworkMgr.getMainIp()
SysMgr.ipAddr = ret
return ret
def __del__(self):
try:
self.close()
except:
pass
class Timeline(object):
"""SVG viewer for timeline segments"""
class Segment(object):
def __init__(self, group, time_start, time_end, extra):
self.group = group
self.time_start = time_start
self.time_end = time_end
self.text = None
self.id = None
self.color = None
self.state = None
self.info = None
self._init_extra(extra)
def _init_extra(self, extra):
if "text" in extra:
self.text = extra["text"]
if "id" in extra:
self.id = extra["id"]
if "color" in extra:
self.color = extra["color"]
if "state" in extra:
self.state = extra["state"]
if "info" in extra:
self.info = extra["info"]
class Config(object):
def _conv_palette(self, palette):
plist = []
for palette_entry in palette:
"""
rgb = [
int(rgb_value)
for rgb_value in re.findall("\d+", palette_entry)
]
"""
color = "rgb%s" % palette_entry
plist.append(color)
return plist
def __init__(self):
self.WIDTH = 1500
self.HEIGHT = 770
self.TIME_AXIS_HEIGHT = 1
self.TICKS = 100
# set item filter #
if "FILTER" in SysMgr.environList:
self.FILTER = SysMgr.environList["FILTER"]
SysMgr.printInfo(
"only specific items [ %s ] are drawn"
% ", ".join(self.FILTER)
)
else:
self.FILTER = []
# set label filter #
if "LABELMIN" in SysMgr.environList:
self.LABEL_SIZE_MIN = UtilMgr.getEnvironNum(
"LABELMIN", isInt=True
)
SysMgr.printInfo(
"only time segments bigger than %s are printed"
% UtilMgr.convNum(self.LABEL_SIZE_MIN)
)
else:
self.LABEL_SIZE_MIN = 0
# set font size #
if "FONTSIZE" in SysMgr.environList:
self.FONT_SIZE = UtilMgr.getEnvironNum("FONTSIZE", isInt=True)
else:
self.FONT_SIZE = 3
# set group font size #
if "GROUPFONTSIZE" in SysMgr.environList:
self.GROUP_FONT_SIZE = UtilMgr.getEnvironNum(
"GROUPFONTSIZE", isInt=True
)
else:
self.GROUP_FONT_SIZE = 0
palette = [
"(0,150,136)",
"(0,188,212)",
"(0,0,128)",
"(0,0,139)",
"(0,0,205)",
"(0,0,255)",
"(0,100,0)",
"(0,128,0)",
"(0,128,128)",
"(0,139,139)",
"(0,191,255)",
"(0,206,209)",
"(0,250,154)",
"(0,255,0)",
"(0,255,127)",
"(0,255,255)",
"(100,149,237)",
"(102,205,170)",
"(103,58,183)",
"(106,90,205)",
"(107,142,35)",
"(121,85,72)",
"(123,104,238)",
"(124,252,0)",
"(127,255,0)",
"(127,255,212)",
"(128,0,0)",
"(128,0,128)",
"(128,128,0)",
"(128,128,128)",
"(135,206,235)",
"(135,206,250)",
"(138,43,226)",
"(139,195,74)",
"(139,0,0)",
"(139,0,139)",
"(139,69,19)",
"(143,188,143)",
"(144,238,144)",
"(147,112,219)",
"(148,0,211)",
"(152,251,152)",
"(153,50,204)",
"(154,205,50)",
"(156,39,176)",
"(158,158,158)",
"(160,82,45)",
"(165,42,42)",
"(173,216,230)",
"(173,255,47)",
"(175,238,238)",
"(176,224,230)",
"(178,34,34)",
"(184,134,11)",
"(186,85,211)",
"(188,143,143)",
"(189,183,107)",
"(192,192,192)",
"(199,21,133)",
"(205,133,63)",
"(205,220,57)",
"(205,92,92)",
"(210,105,30)",
"(210,180,140)",
"(216,191,216)",
"(218,112,214)",
"(218,165,32)",
"(219,112,147)",
"(220,20,60)",
"(221,160,221)",
"(222,184,135)",
"(224,255,255)",
"(233,150,122)",
"(233,30,99)",
"(238,130,238)",
"(238,232,170)",
"(240,128,128)",
"(240,230,140)",
"(244,67,54)",
"(244,164,96)",
"(245,222,179)",
"(245,245,220)",
"(25,25,112)",
"(250,128,114)",
"(250,235,215)",
"(250,250,210)",
"(255,0,0)",
"(255,0,255)",
"(255,105,180)",
"(255,127,80)",
"(255,140,0)",
"(255,152,0)",
"(255,160,122)",
"(255,165,0)",
"(255,182,193)",
"(255,192,203)",
"(255,193,7)",
"(255,20,147)",
"(255,215,0)",
"(255,228,196)",
"(255,235,205)",
"(255,235,59)",
"(255,248,220)",
"(255,250,205)",
"(255,255,0)",
"(255,255,224)",
"(255,69,0)",
"(255,87,34)",
"(255,99,71)",
"(3,169,244)",
"(30,144,255)",
"(32,178,170)",
"(33,150,243)",
"(34,139,34)",
"(46,139,87)",
"(47,79,79)",
"(50,205,50)",
"(60,179,113)",
"(63,81,181)",
"(64,224,208)",
"(65,105,225)",
"(70,130,180)",
"(72,209,204)",
"(72,61,139)",
"(75,0,130)",
"(76,175,80)",
"(85,107,47)",
"(95,158,160)",
"(96,125,139)",
]
self.PALETTE = self._conv_palette(palette)
# shuffle list #
random = SysMgr.getPkg("random", False)
if random:
random.shuffle(self.PALETTE)
@staticmethod
def _load(fileName=None, data=None):
if fileName:
with open(fileName) as fd:
data = fd.read()
data = UtilMgr.convStr2Dict(data)
elif not data:
SysMgr.printErr("no path or data for timeline config")
sys.exit(-1)
config = Timeline.Config()
config.WIDTH = data.get("width", 20000)
config.HEIGHT = data.get("height", 4000)
config.FONT_SIZE = data.get("font_size", 3)
config.TICKS = data.get("time_ticks", 5)
config.TIME_AXIS_HEIGHT = data.get("time_axis_height", 5)
config.PALETTE = config._conv_palette(data.get("palette", []))
config.TIMEUNIT = data.get("time_unit", None)
config.TIMEFACTOR = data.get("time_factor", 1)
if config.LABEL_SIZE_MIN == 0:
config.LABEL_SIZE_MIN = data.get("label_size_min", 5)
return config
def __init__(self, title, segments, time_unit, fontsize, config, tasks=[]):
self.title = title
self.segments = segments
self.time_unit = time_unit
self.config = config
self.time_start = min(
segments, key=lambda segment: segment.time_start
).time_start
self.time_end = max(
segments, key=lambda segment: segment.time_end
).time_end
self.segment_groups = sorted(
list(map(long, set(s.group for s in self.segments)))
)
self.segment_groups = list(map(str, self.segment_groups))
self.groups = len(self.segment_groups)
self.scaled_height = self.config.HEIGHT / self.groups
self.group_list = list(self.segment_groups)
self.group_stat = [
{
"cnt": 0,
"du_min": 0,
"du_max": 0,
"du_list": [],
"inter_min": 0,
"inter_max": 0,
"inter_list": [],
"prev": 0,
}
for _ in xrange(len(self.group_list))
]
try:
self.ratio = self.config.WIDTH / float(
self.time_end - self.time_start
)
except SystemExit:
sys.exit(0)
except:
SysMgr.printErr(
"failed to recognize timeline because start and end are same"
)
sys.exit(-1)
self.last_group_segment = {}
self.last_group_time = {}
self.height_group_pos = {}
self.last_iogroup_segment = {}
self.last_iogroup_time = {}
self.height_iogroup_pos = {}
# apply task converter #
try:
self.tasks = {}
if tasks:
for task in tasks:
if task in Timeline.conv_table:
new = Timeline.conv_table[task]
self.tasks[new] = tasks[task]
elif type(tasks) is dict:
self.tasks[task] = tasks[task]
except SystemExit:
sys.exit(0)
except:
SysMgr.printErr("failed to change tasks in timeline", True)
sys.exit(-1)
# time factor #
if hasattr(self.config, "TIMEFACTOR"):
self.time_factor = self.config.TIMEFACTOR
else:
self.time_factor = 1
# task color #
if self.tasks:
self.color_map = self._build_task_color_map()
else:
self.color_map = self._build_color_map()
# update font size #
if fontsize and self.config:
self.config.FONT_SIZE = fontsize
def _build_task_color_map(self):
color_map = {}
palette = self.config.PALETTE
for i, group in enumerate(self.tasks):
color_map[group] = palette[i % len(palette)]
return color_map
def _build_color_map(self):
color_map = {}
palette = self.config.PALETTE
segment_groups = self.segment_groups
for i, group in enumerate(segment_groups):
color_map[group] = palette[i % len(palette)]
return color_map
def _draw_grid(self, dwg):
for x in xrange(0, self.config.WIDTH, self.config.TICKS):
dwg.add(
dwg.line(
(x, 0),
(x, self.config.HEIGHT),
stroke="black",
stroke_width=0.1,
)
)
def _draw_group_stat(self, dwg):
# set group font size #
if self.config.GROUP_FONT_SIZE > 0:
fontsize = self.config.GROUP_FONT_SIZE
else:
fontsize = self.scaled_height / 4
idx = 0
convNum = UtilMgr.convNum
for y_tick in xrange(self.config.HEIGHT):
try:
stats = self.group_stat[idx]
idx += 1
# count #
count = stats["cnt"]
if count == 0:
continue
# build string #
statstr = "Cnt: %s" % convNum(count)
# interval #
if count > 1:
try:
inter = stats["inter_list"]
inter_avg = long(sum(inter) / (len(inter)))
except SystemExit:
sys.exit(0)
except:
inter_avg = 0
inter_std = UtilMgr.getStdev(inter)
statstr += (
", IntMin: %s, IntMax: %s, IntAvg: %s, IntStd: %s"
% (
convNum(stats["inter_min"]),
convNum(stats["inter_max"]),
convNum(inter_avg),
convNum(inter_std),
)
)
# duration #
if stats["du_min"] > 0:
try:
du = stats["du_list"]
du_avg = long(sum(du) / (len(du)))
except SystemExit:
sys.exit(0)
except:
du_avg = 0
du_std = UtilMgr.getStdev(du)
statstr += (
", DuMin: %s, DuMax: %s, DuAvg: %s, DuStd: %s"
% (
convNum(stats["du_min"]),
convNum(stats["du_max"]),
convNum(du_avg),
convNum(du_std),
)
)
except SystemExit:
sys.exit(0)
except:
continue
y_tick *= self.scaled_height
dwg.add(
dwg.text(
statstr,
(2, y_tick + self.scaled_height / 2),
font_size=fontsize / 2,
fill="rgb(200,200,200)",
)
)
def _draw_group_axis(self, dwg, yval):
dwg.add(
dwg.rect(
(0, 0),
(self.config.TIME_AXIS_HEIGHT, self.config.HEIGHT),
fill="black",
)
)
# set group font size #
if self.config.GROUP_FONT_SIZE > 0:
fontsize = self.config.GROUP_FONT_SIZE
else:
fontsize = self.scaled_height / 2
idx = 0
groupList = list(self.segment_groups)
for y_tick in xrange(self.config.HEIGHT):
try:
name = groupList[idx]
idx += 1
except:
continue
y_tick *= self.scaled_height
dwg.add(
dwg.line(
(0, y_tick),
(self.config.WIDTH, y_tick),
stroke="black",
stroke_width=2,
)
)
dwg.add(
dwg.text(
name,
(2, y_tick + self.scaled_height),
font_size=fontsize,
fill="rgb(200,200,200)",
)
)
# add info #
addinfo = yval[name] if yval and name in yval else ""
name = str(name)
if not addinfo and self.tasks and name in self.tasks:
addinfo = self.tasks[name]
if addinfo:
x = 2 * self.scaled_height * len(name) / 5
dwg.add(
dwg.text(
addinfo,
(x, y_tick + self.scaled_height),
font_size=fontsize / 2,
fill="rgb(200,200,200)",
)
)
def _draw_time_axis(self, dwg, start=0, annotation=None):
dwg.add(
dwg.rect(
(0, self.config.HEIGHT),
(self.config.WIDTH, self.config.TIME_AXIS_HEIGHT),
fill="black",
)
)
y_time_tick = self.config.HEIGHT + self.config.TIME_AXIS_HEIGHT / 2
ratio = 1 / self.ratio
# set time delta #
start = float(start) / self.time_factor
# create the drawing group #
g = dwg.add(dwg.g())
if annotation:
g.set_desc(annotation)
for x_tick_time in xrange(0, self.config.WIDTH, self.config.TICKS):
abs_x_tick_time = (x_tick_time * ratio) + start
tick_time = "{:10}".format(long(abs_x_tick_time))
g.add(
dwg.text(
"%s %s" % (UtilMgr.convNum(tick_time), self.time_unit),
(x_tick_time, y_time_tick + self.config.FONT_SIZE * 5),
font_size=self.config.FONT_SIZE * 5,
color="rgb(255,255,255)",
)
)
def _draw_background(self, dwg):
dwg.add(
dwg.rect(
(0, 0),
(self.config.WIDTH, self.config.HEIGHT),
fill="rgb(245,245,245)",
)
)
# set title #
if self.title:
title = self.title
else:
title = "Guider Timeline"
# set font size for title #
fontsize = self.config.FONT_SIZE * 10
dwg.add(
dwg.text(
title,
(
(self.config.WIDTH / 2) - (len(title) * fontsize / 4),
fontsize,
),
font_size=fontsize,
font_weight="bolder",
fill="rgb(200,200,200)",
)
)
def _draw_segments(self, dwg, start=0):
# set time delta #
start = float(start) / self.time_factor
for idx, segment in enumerate(
sorted(self.segments, key=lambda e: len(e.state))
):
UtilMgr.printProgress(idx, len(self.segments))
self._draw_segment(segment, dwg, start)
if self.segments:
UtilMgr.deleteProgress()
def _draw_segment(self, segment, dwg, start=0):
x0 = float(segment.time_start - self.time_start) * self.ratio
x1 = float(segment.time_end - self.time_start) * self.ratio
group_idx = self.group_list.index(segment.group)
y0 = self.scaled_height * float(group_idx % self.groups)
y1 = self.scaled_height * float((group_idx % self.groups) + 1)
scaled_width = x1 - x0
scaled_top_height = y0 + (self.scaled_height / 7)
scaled_bottom_height = y1 - (self.scaled_height * 0.25)
duration = segment.time_end - segment.time_start
time_end = segment.time_end + start - self.time_start
strokeSize = 3.5
# check filter #
if self.config.FILTER and not UtilMgr.isValidStr(
segment.text, self.config.FILTER
):
return
# get color ID #
if segment.color:
color = segment.color
else:
if segment.id:
colorid = segment.id
else:
colorid = group_idx
# get real color via ID #
try:
color = self.color_map[str(colorid)]
except SystemExit:
sys.exit(0)
except:
try:
cidx = long(colorid) % len(self.color_map)
color = self.color_map[list(self.color_map)[cidx]]
self.color_map[str(colorid)] = color
except SystemExit:
sys.exit(0)
except:
color = self.color_map[list(self.color_map)[0]]
# check stroke option #
if self.stroke_text and UtilMgr.isValidStr(
segment.text, self.stroke_text
):
stroke = "rgb(255,0,0)"
stroke_width = 1
else:
stroke = "none"
stroke_width = 0
# update count stat #
stats = self.group_stat[group_idx]
stats["cnt"] += 1
# update interval stats #
if stats["prev"] > 0:
interval = segment.time_start - stats["prev"]
else:
interval = 0
stats["prev"] = segment.time_start
if stats["inter_min"] == 0 or stats["inter_min"] > interval:
stats["inter_min"] = interval
if stats["inter_max"] == 0 or stats["inter_max"] < interval:
stats["inter_max"] = interval
stats["inter_list"].append(interval)
# apply stroke by interval #
if self.stroke_interval > 0 and self.stroke_interval <= interval:
stroke = "rgb(255,0,0)"
stroke_width = 1
# update duration stats #
if stats["du_min"] == 0 or stats["du_min"] > duration:
stats["du_min"] = duration
if stats["du_max"] == 0 or stats["du_max"] < duration:
stats["du_max"] = duration
stats["du_list"].append(duration)
# apply stroke by duration #
if self.stroke_duration > 0 and self.stroke_duration <= duration:
stroke = "rgb(255,0,0)"
stroke_width = 1
# draw bold line for core off #
if segment.state == "OFF":
dwg.add(
dwg.line(
(x0, y0), (x1, y0), stroke="gray", stroke_width=strokeSize
)
)
return
# draw circle and text for event #
if segment.state and segment.state.startswith("EVENT"):
if segment.state == "EVENT_MARK":
font_size = self.config.FONT_SIZE
elif segment.state == "EVENT_USER":
font_size = self.config.FONT_SIZE * 3
else:
font_size = self.config.FONT_SIZE
dwg.add(
dwg.circle(
center=(x0, y0),
r=font_size / 2,
stroke="darkgreen",
fill="darkgreen",
)
)
# draw text #
dwg.add(
dwg.text(
segment.text,
(x0 + font_size, y0),
fill="darkgreen",
stroke="none",
font_size=font_size,
font_weight="bolder",
)
)
return
# define shortcut and duration string #
convNum = UtilMgr.convNum
durationstr = convNum(duration)
if hasattr(segment, "info") and segment.info:
info = "\n%s" % segment.info
else:
info = ""
# create the drawing group #
g = dwg.add(dwg.g())
g.set_desc(
"%s %s / ~%s (%s)%s"
% (
segment.text,
durationstr,
convNum(time_end),
self.time_unit,
info,
)
)
# draw line for block_read status #
if segment.state == "RD":
g.add(
dwg.rect(
(x0, scaled_bottom_height),
(scaled_width, self.scaled_height * 0.25),
rx=1,
ry=1,
fill="purple",
fill_opacity=0.5,
stroke=stroke,
stroke_width=stroke_width,
)
)
# draw line for block_write status #
elif segment.state == "WR":
g.add(
dwg.rect(
(x0, scaled_bottom_height),
(scaled_width, self.scaled_height * 0.25),
rx=1,
ry=1,
fill="darkcyan",
fill_opacity=0.5,
stroke=stroke,
stroke_width=stroke_width,
)
)
# draw line for syscall status #
elif segment.state == "SYSCALL":
g.add(
dwg.rect(
(x0, y0),
(scaled_width, self.scaled_height * 0.5),
rx=1,
ry=1,
fill=color,
fill_opacity=0.5,
stroke=stroke,
stroke_width=stroke_width,
)
)
# draw line for sched status #
else:
# draw CPU timeslice #
g.add(
dwg.rect(
(x0, y0),
(scaled_width, self.scaled_height),
rx=1,
ry=1,
fill=color,
fill_opacity=0.5,
stroke=stroke,
stroke_width=stroke_width,
)
)
# draw preempted status #
if segment.state == "R":
g.add(
dwg.line(
(x1, y0),
(x1, scaled_top_height),
stroke="red",
stroke_width=strokeSize,
)
)
# draw wait status #
elif segment.state == "D":
g.add(
dwg.line(
(x1, y0),
(x1, scaled_top_height),
stroke="black",
stroke_width=strokeSize,
)
)
# check label flag #
if (
not SysMgr.showAll
and not "LABEL" in SysMgr.environList
and not "LABELMIN" in SysMgr.environList
):
return
# check duration #
elif not duration or duration < self.config.LABEL_SIZE_MIN:
return
# convert duration to text #
duration = "~%s" % convNum(durationstr)
# I/O #
if segment.state in ("RD", "WR"):
# initialize group data #
self.last_iogroup_segment.setdefault(group_idx, None)
self.last_iogroup_time.setdefault(group_idx, x0)
# define data #
last_iogroup_segment = self.last_iogroup_segment[group_idx]
last_iogroup_time = self.last_iogroup_time[group_idx]
# set text attributes for block_read #
if segment.state == "RD":
if (
last_iogroup_segment == segment.text
and x0 - last_iogroup_time < self.config.TICKS
):
segment_label = durationstr
font_size = self.config.FONT_SIZE - 1
else:
segment_label = "[R] %s %s" % (segment.text, durationstr)
font_size = self.config.FONT_SIZE - 0.7
color = "rgb(128,0,128)"
# set text attributes for block_write #
elif segment.state == "WR":
if (
last_iogroup_segment == segment.text
and x0 - last_iogroup_time < self.config.TICKS
):
segment_label = durationstr
font_size = self.config.FONT_SIZE - 1
else:
segment_label = "[W] %s %s" % (segment.text, durationstr)
font_size = self.config.FONT_SIZE - 0.7
color = "rgb(0,139,139)"
# update group info #
self.last_iogroup_segment[group_idx] = segment.text
self.last_iogroup_time[group_idx] = x0
self.height_iogroup_pos.setdefault(group_idx, 0)
# set text position #
scaled_pos = self.scaled_height * 0.75
self.height_iogroup_pos[group_idx] += self.config.FONT_SIZE
height_pos = self.height_iogroup_pos[group_idx]
if height_pos + scaled_pos >= self.scaled_height:
height_pos = self.height_iogroup_pos[
group_idx
] = self.config.FONT_SIZE
# CPU & SYSCALL #
else:
# SYSCALL #
if segment.state == "SYSCALL":
prefix = "[S] "
else:
prefix = ""
# initialize group data #
self.last_group_segment.setdefault(group_idx, None)
self.last_group_time.setdefault(group_idx, x0)
# set text attributes for same task #
if (
self.last_group_segment[group_idx] == segment.text
and x0 - self.last_group_time[group_idx] < self.config.TICKS
):
segment_label = durationstr
color = "rgb(50,50,50)"
font_size = self.config.FONT_SIZE - 1
# set text attributes for new task #
else:
segment_label = "%s%s %s" % (prefix, segment.text, durationstr)
color = "rgb(255,0,0)"
font_size = self.config.FONT_SIZE - 0.5
# update group info #
self.last_group_segment[group_idx] = segment.text
self.last_group_time[group_idx] = x0
self.height_group_pos.setdefault(group_idx, 0)
# set text position #
scaled_pos = self.scaled_height * 0.15
self.height_group_pos[group_idx] += self.config.FONT_SIZE
height_pos = self.height_group_pos[group_idx]
if height_pos + scaled_pos * 2.5 >= self.scaled_height:
height_pos = self.height_group_pos[group_idx] = 0
# set text position #
xpos = x0
ypos = y0 + scaled_pos + height_pos
# draw text #
dwg.add(
dwg.text(
segment_label,
(xpos, ypos),
fill=color,
stroke="none",
font_size=font_size,
font_weight="normal",
transform="rotate(0,%s,%s)" % (xpos, ypos),
)
)
def draw(self, dwg, start=0, annotation=None, yval=None):
self._draw_background(dwg)
self._draw_grid(dwg)
self._draw_group_axis(dwg, yval)
self._draw_time_axis(dwg, start, annotation=annotation)
self._draw_segments(dwg, start)
self._draw_group_stat(dwg)
@staticmethod
def load(
fileName=None,
data=None,
config=None,
tasks=None,
begin=0,
end=0,
duration=0,
durationMin=0,
):
if fileName:
with open(fileName) as json_file:
# get json object #
json = SysMgr.getPkg("json")
data = json.load(json_file)
elif not data:
SysMgr.printErr("no path or data for timeline input")
sys.exit(-1)
# get default timeunit #
time_unit = ""
if "time_unit" in data:
time_unit = data["time_unit"]
time_unit = time_unit.lower()
# get title #
if "title" in data:
title = data["title"]
else:
title = ""
# get font size #
if "names" in data and data["names"]:
if tasks:
tasks.update(data["names"])
else:
tasks = data["names"]
# get font size #
if "font_size" in data:
fontsize = data["font_size"]
else:
fontsize = None
# get configured timeunit #
time_factor = 1.0
if hasattr(config, "TIMEUNIT") and config.TIMEUNIT:
new_time_unit = config.TIMEUNIT.lower()
if time_unit == new_time_unit:
pass
elif time_unit == "us":
if new_time_unit == "ms":
time_factor = 1 / 1000.0
elif new_time_unit == "sec":
time_factor = 1 / 1000000.0
else:
SysMgr.printErr(
"no support '%s' unit for timeline" % new_time_unit
)
elif time_unit == "ms":
if new_time_unit == "us":
time_factor = 1000.0
elif new_time_unit == "sec":
time_factor = 1 / 1000.0
else:
SysMgr.printErr(
"no support '%s' unit for timeline" % new_time_unit
)
else:
SysMgr.printErr(
"no support '%s' unit for timeline" % new_time_unit
)
time_unit = new_time_unit
config.TIMEFACTOR = time_factor
# print time unit #
if time_unit:
SysMgr.printInfo("apply '%s' in time unit" % time_unit)
# load segments #
segments = Timeline._load_segments(
data, time_factor, begin, end, duration, durationMin
)
if not segments:
return None
return Timeline(title, segments, time_unit, fontsize, config, tasks)
@staticmethod
def _load_segments(
data, time_factor=1, begin=0, end=0, duration=0, durationMin=0
):
segments = []
for segment_data in sorted(
data["segments"], key=lambda e: e["time_start"]
):
# convert group #
group = str(segment_data["group"])
group_num = long(group)
if group in Timeline.conv_table:
group = Timeline.conv_table[group]
# apply core filter ;) #
if SysMgr.perCoreDrawList:
if not group_num in SysMgr.perCoreDrawList:
continue
# verify time #
if segment_data["time_start"] > segment_data["time_end"]:
SysMgr.printWarn(
"time_start is bigger than time_end for %s" % segment_data
)
continue
# apply common duration #
time_start = long(segment_data["time_start"] * time_factor)
if duration > 0:
time_end = time_start + duration
else:
time_end = long(segment_data["time_end"] * time_factor)
# apply minimum duration #
if durationMin > 0:
diff = time_end - time_start
if durationMin > diff:
time_end = time_start + durationMin
# check time #
if end > 0 and time_end > end:
time_end = end
if time_start > end:
continue
if begin > 0 and time_start < begin:
if time_end < begin:
continue
time_start = begin
# add segment #
segments.append(
Timeline.Segment(group, time_start, time_end, segment_data)
)
return segments
class Ext4Analyzer(object):
"""Analyzer for ext4"""
FILE_TYPE = {
0: "unkn",
1: "file",
2: "dir",
3: "chr",
4: "blk",
5: "fifo",
6: "sock",
7: "sym",
}
def __init__(self, path, verb=False):
# get ctypes object #
SysMgr.importPkgItems("ctypes")
# init variables #
self.volume = None
self.inodeList = {}
self.failDirList = {}
# start loading classes #
# refer to https://github.com/cubinator/ext4 #
class Ext4Error(Exception):
"""
Base class for all custom errors
"""
pass
class BlockMapError(Ext4Error):
# a requested file_block is not mapped to disk
pass
class EndOfStreamError(Ext4Error):
# BlockReader reads beyond the end of the volume's underlying stream
pass
class MagicError(Ext4Error):
# a structures magic value is wrong and ignoreMagic is False
pass
class ext4_struct(LittleEndianStructure):
"""
Simplifies access to *_lo and *_hi fields
"""
def __getattr__(self, name):
"""
Enables reading *_lo and *_hi fields together.
"""
try:
# Combining *_lo and *_hi fields
lo_field = LittleEndianStructure.__getattribute__(
type(self), name + "_lo"
)
size = lo_field.size
lo = lo_field.__get__(self)
hi = LittleEndianStructure.__getattribute__(
self, name + "_hi"
)
return (hi << (8 * size)) | lo
except AttributeError:
return LittleEndianStructure.__getattribute__(self, name)
def __setattr__(self, name, value):
"""
Enables setting *_lo and *_hi fields together.
"""
try:
# Combining *_lo and *_hi fields
lo_field = (
lo_field
) = LittleEndianStructure.__getattribute__(
type(self), name + "_lo"
)
size = lo_field.size
lo_field.__set__(self, value & ((1 << (8 * size)) - 1))
LittleEndianStructure.__setattr__(
self, name + "_hi", value >> (8 * size)
)
except AttributeError:
LittleEndianStructure.__setattr__(self, name, value)
class ext4_dir_entry_2(ext4_struct):
_fields_ = [
("inode", c_uint), # 0x0
("rec_len", c_ushort), # 0x4
("name_len", c_ubyte), # 0x6
("file_type", c_ubyte) # 0x7
# Variable length field "name" missing at 0x8
]
@classmethod
def _from_buffer_copy(cls, raw, offset=0, platform64=True):
# pylint: disable=no-self-argument
struct = ext4_dir_entry_2.from_buffer_copy(raw, offset)
struct.name = raw[
offset + 0x8 : offset + 0x8 + struct.name_len
]
return struct
class ext4_extent(ext4_struct):
_fields_ = [
("ee_block", c_uint), # 0x0000
("ee_len", c_ushort), # 0x0004
("ee_start_hi", c_ushort), # 0x0006
("ee_start_lo", c_uint), # 0x0008
]
class ext4_extent_header(ext4_struct):
_fields_ = [
("eh_magic", c_ushort), # 0x0000, Must be 0xF30A
("eh_entries", c_ushort), # 0x0002
("eh_max", c_ushort), # 0x0004
("eh_depth", c_ushort), # 0x0006
("eh_generation", c_uint), # 0x0008
]
class ext4_extent_idx(ext4_struct):
_fields_ = [
("ei_block", c_uint), # 0x0000
("ei_leaf_lo", c_uint), # 0x0004
("ei_leaf_hi", c_ushort), # 0x0008
("ei_unused", c_ushort), # 0x000A
]
class ext4_group_descriptor(ext4_struct):
_fields_ = [
("bg_block_bitmap_lo", c_uint), # 0x0000
("bg_inode_bitmap_lo", c_uint), # 0x0004
("bg_inode_table_lo", c_uint), # 0x0008
("bg_free_blocks_count_lo", c_ushort), # 0x000C
("bg_free_inodes_count_lo", c_ushort), # 0x000E
("bg_used_dirs_count_lo", c_ushort), # 0x0010
("bg_flags", c_ushort), # 0x0012
("bg_exclude_bitmap_lo", c_uint), # 0x0014
("bg_block_bitmap_csum_lo", c_ushort), # 0x0018
("bg_inode_bitmap_csum_lo", c_ushort), # 0x001A
("bg_itable_unused_lo", c_ushort), # 0x001C
("bg_checksum", c_ushort), # 0x001E
# 64-bit fields
("bg_block_bitmap_hi", c_uint), # 0x0020
("bg_inode_bitmap_hi", c_uint), # 0x0024
("bg_inode_table_hi", c_uint), # 0x0028
("bg_free_blocks_count_hi", c_ushort), # 0x002C
("bg_free_inodes_count_hi", c_ushort), # 0x002E
("bg_used_dirs_count_hi", c_ushort), # 0x0030
("bg_itable_unused_hi", c_ushort), # 0x0032
("bg_exclude_bitmap_hi", c_uint), # 0x0034
("bg_block_bitmap_csum_hi", c_ushort), # 0x0038
("bg_inode_bitmap_csum_hi", c_ushort), # 0x003A
("bg_reserved", c_uint), # 0x003C
]
@classmethod
def _from_buffer_copy(cls, raw, offset=0, platform64=True):
# pylint: disable=no-self-argument
struct = ext4_group_descriptor.from_buffer_copy(raw, offset)
if not platform64:
struct.bg_block_bitmap_hi = 0
struct.bg_inode_bitmap_hi = 0
struct.bg_inode_table_hi = 0
struct.bg_free_blocks_count_hi = 0
struct.bg_free_inodes_count_hi = 0
struct.bg_used_dirs_count_hi = 0
struct.bg_itable_unused_hi = 0
struct.bg_exclude_bitmap_hi = 0
struct.bg_block_bitmap_csum_hi = 0
struct.bg_inode_bitmap_csum_hi = 0
struct.bg_reserved = 0
return struct
class ext4_inode(ext4_struct):
"""
Every field passing 128 bytes is "additional data",
whose size is specified by i_extra_isize.
"""
EXT2_GOOD_OLD_INODE_SIZE = 128
# i_mode
S_IXOTH = 0x1 # Others can execute
S_IWOTH = 0x2 # Others can write
S_IROTH = 0x4 # Others can read
S_IXGRP = 0x8 # Group can execute
S_IWGRP = 0x10 # Group can write
S_IRGRP = 0x20 # Group can read
S_IXUSR = 0x40 # Owner can execute
S_IWUSR = 0x80 # Owner can write
S_IRUSR = 0x100 # Owner can read
S_ISVTX = 0x200 # Sticky bit (only owner can delete)
S_ISGID = 0x400 # Set GID
S_ISUID = 0x800 # Set UID
S_IFIFO = 0x1000 # FIFO device (named pipe)
S_IFCHR = 0x2000 # Character device
S_IFDIR = 0x4000 # Directory
S_IFBLK = 0x6000 # Block device
S_IFREG = 0x8000 # Regular file
S_IFLNK = 0xA000 # Symbolic link
S_IFSOCK = 0xC000 # Socket
# i_flags
EXT4_INDEX_FL = 0x1000 # Uses hash trees
EXT4_EXTENTS_FL = 0x80000 # Uses extents
EXT4_EA_INODE_FL = 0x200000 # Inode stores large xattr
EXT4_INLINE_DATA_FL = 0x10000000 # Has inline data
_fields_ = [
("i_mode", c_ushort), # 0x0000
("i_uid_lo", c_ushort), # 0x0002
("i_size_lo", c_uint), # 0x0004
("i_atime", c_uint), # 0x0008
("i_ctime", c_uint), # 0x000C
("i_mtime", c_uint), # 0x0010
("i_dtime", c_uint), # 0x0014
("i_gid_lo", c_ushort), # 0x0018
("i_links_count", c_ushort), # 0x001A
("i_blocks_lo", c_uint), # 0x001C
("i_flags", c_uint), # 0x0020
("osd1", c_uint), # 0x0024
("i_block", c_uint * 15), # 0x0028
("i_generation", c_uint), # 0x0064
("i_file_acl_lo", c_uint), # 0x0068
("i_size_hi", c_uint), # 0x006C
("i_obso_faddr", c_uint), # 0x0070
("i_osd2_blocks_high", c_ushort), # 0x0074
("i_file_acl_hi", c_ushort), # 0x0076
("i_uid_hi", c_ushort), # 0x0078
("i_gid_hi", c_ushort), # 0x007A
("i_osd2_checksum_lo", c_ushort), # 0x007C
("i_osd2_reserved", c_ushort), # 0x007E
("i_extra_isize", c_ushort), # 0x0080
("i_checksum_hi", c_ushort), # 0x0082
("i_ctime_extra", c_uint), # 0x0084
("i_mtime_extra", c_uint), # 0x0088
("i_atime_extra", c_uint), # 0x008C
("i_crtime", c_uint), # 0x0090
("i_crtime_extra", c_uint), # 0x0094
("i_version_hi", c_uint), # 0x0098
("i_projid", c_uint), # 0x009C
]
class ext4_superblock(ext4_struct):
# Default value for s_desc_size, if INCOMPAT_64BIT is not set
EXT2_MIN_DESC_SIZE = 0x20
# Default value for s_desc_size, if INCOMPAT_64BIT is set
EXT2_MIN_DESC_SIZE_64BIT = 0x40
# s_feature_incompat
# Uses 64-bit features
INCOMPAT_64BIT = 0x80
# Directory entries record file type (instead of inode flags)
INCOMPAT_FILETYPE = 0x2
_fields_ = [
("s_inodes_count", c_uint), # 0x0000
("s_blocks_count_lo", c_uint), # 0x0004
("s_r_blocks_count_lo", c_uint), # 0x0008
("s_free_blocks_count_lo", c_uint), # 0x000C
("s_free_inodes_count", c_uint), # 0x0010
("s_first_data_block", c_uint), # 0x0014
("s_log_block_size", c_uint), # 0x0018
("s_log_cluster_size", c_uint), # 0x001C
("s_blocks_per_group", c_uint), # 0x0020
("s_clusters_per_group", c_uint), # 0x0024
("s_inodes_per_group", c_uint), # 0x0028
("s_mtime", c_uint), # 0x002C
("s_wtime", c_uint), # 0x0030
("s_mnt_count", c_ushort), # 0x0034
("s_max_mnt_count", c_ushort), # 0x0036
("s_magic", c_ushort), # 0x0038
("s_state", c_ushort), # 0x003A
("s_errors", c_ushort), # 0x003C
("s_minor_rev_level", c_ushort), # 0x003E
("s_lastcheck", c_uint), # 0x0040
("s_checkinterval", c_uint), # 0x0044
("s_creator_os", c_uint), # 0x0048
("s_rev_level", c_uint), # 0x004C
("s_def_resuid", c_ushort), # 0x0050
("s_def_resgid", c_ushort), # 0x0052
("s_first_ino", c_uint), # 0x0054
("s_inode_size", c_ushort), # 0x0058
("s_block_group_nr", c_ushort), # 0x005A
("s_feature_compat", c_uint), # 0x005C
("s_feature_incompat", c_uint), # 0x0060
("s_feature_ro_compat", c_uint), # 0x0064
("s_uuid", c_ubyte * 16), # 0x0068
("s_volume_name", c_char * 16), # 0x0078
("s_last_mounted", c_char * 64), # 0x0088
("s_algorithm_usage_bitmap", c_uint), # 0x00C8
("s_prealloc_blocks", c_ubyte), # 0x00CC
("s_prealloc_dir_blocks", c_ubyte), # 0x00CD
("s_reserved_gdt_blocks", c_ushort), # 0x00CE
("s_journal_uuid", c_ubyte * 16), # 0x00D0
("s_journal_inum", c_uint), # 0x00E0
("s_journal_dev", c_uint), # 0x00E4
("s_last_orphan", c_uint), # 0x00E8
("s_hash_seed", c_uint * 4), # 0x00EC
("s_def_hash_version", c_ubyte), # 0x00FC
("s_jnl_backup_type", c_ubyte), # 0x00FD
("s_desc_size", c_ushort), # 0x00FE
("s_default_mount_opts", c_uint), # 0x0100
("s_first_meta_bg", c_uint), # 0x0104
("s_mkfs_time", c_uint), # 0x0108
("s_jnl_blocks", c_uint * 17), # 0x010C
# 64-bit fields
("s_blocks_count_hi", c_uint), # 0x0150
("s_r_blocks_count_hi", c_uint), # 0x0154
("s_free_blocks_count_hi", c_uint), # 0x0158
("s_min_extra_isize", c_ushort), # 0x015C
("s_want_extra_isize", c_ushort), # 0x015E
("s_flags", c_uint), # 0x0160
("s_raid_stride", c_ushort), # 0x0164
("s_mmp_interval", c_ushort), # 0x0166
("s_mmp_block", c_ulonglong), # 0x0168
("s_raid_stripe_width", c_uint), # 0x0170
("s_log_groups_per_flex", c_ubyte), # 0x0174
("s_checksum_type", c_ubyte), # 0x0175
("s_reserved_pad", c_ushort), # 0x0176
("s_kbytes_written", c_ulonglong), # 0x0178
("s_snapshot_inum", c_uint), # 0x0180
("s_snapshot_id", c_uint), # 0x0184
("s_snapshot_r_blocks_count", c_ulonglong), # 0x0188
("s_snapshot_list", c_uint), # 0x0190
("s_error_count", c_uint), # 0x0194
("s_first_error_time", c_uint), # 0x0198
("s_first_error_ino", c_uint), # 0x019C
("s_first_error_block", c_ulonglong), # 0x01A0
("s_first_error_func", c_ubyte * 32), # 0x01A8
("s_first_error_line", c_uint), # 0x01C8
("s_last_error_time", c_uint), # 0x01CC
("s_last_error_ino", c_uint), # 0x01D0
("s_last_error_line", c_uint), # 0x01D4
("s_last_error_block", c_ulonglong), # 0x01D8
("s_last_error_func", c_ubyte * 32), # 0x01E0
("s_mount_opts", c_ubyte * 64), # 0x0200
("s_usr_quota_inum", c_uint), # 0x0240
("s_grp_quota_inum", c_uint), # 0x0244
("s_overhead_blocks", c_uint), # 0x0248
("s_backup_bgs", c_uint * 2), # 0x024C
("s_encrypt_algos", c_ubyte * 4), # 0x0254
("s_encrypt_pw_salt", c_ubyte * 16), # 0x0258
("s_lpf_ino", c_uint), # 0x0268
("s_prj_quota_inum", c_uint), # 0x026C
("s_checksum_seed", c_uint), # 0x0270
("s_reserved", c_uint * 98), # 0x0274
("s_checksum", c_uint), # 0x03FC
]
@classmethod
def _from_buffer_copy(cls, raw, platform64=True):
# pylint: disable=no-self-argument
struct = ext4_superblock.from_buffer_copy(raw)
if not platform64:
struct.s_blocks_count_hi = 0
struct.s_r_blocks_count_hi = 0
struct.s_free_blocks_count_hi = 0
struct.s_min_extra_isize = 0
struct.s_want_extra_isize = 0
struct.s_flags = 0
struct.s_raid_stride = 0
struct.s_mmp_interval = 0
struct.s_mmp_block = 0
struct.s_raid_stripe_width = 0
struct.s_log_groups_per_flex = 0
struct.s_checksum_type = 0
struct.s_reserved_pad = 0
struct.s_kbytes_written = 0
struct.s_snapshot_inum = 0
struct.s_snapshot_id = 0
struct.s_snapshot_r_blocks_count = 0
struct.s_snapshot_list = 0
struct.s_error_count = 0
struct.s_first_error_time = 0
struct.s_first_error_ino = 0
struct.s_first_error_block = 0
struct.s_first_error_func = 0
struct.s_first_error_line = 0
struct.s_last_error_time = 0
struct.s_last_error_ino = 0
struct.s_last_error_line = 0
struct.s_last_error_block = 0
struct.s_last_error_func = 0
struct.s_mount_opts = 0
struct.s_usr_quota_inum = 0
struct.s_grp_quota_inum = 0
struct.s_overhead_blocks = 0
struct.s_backup_bgs = 0
struct.s_encrypt_algos = 0
struct.s_encrypt_pw_salt = 0
struct.s_lpf_ino = 0
struct.s_prj_quota_inum = 0
struct.s_checksum_seed = 0
struct.s_reserved = 0
struct.s_checksum = 0
if struct.s_desc_size != 0:
return struct
if (
struct.s_feature_incompat & ext4_superblock.INCOMPAT_64BIT
) == 0:
struct.s_desc_size = ext4_superblock.EXT2_MIN_DESC_SIZE
else:
struct.s_desc_size = (
ext4_superblock.EXT2_MIN_DESC_SIZE_64BIT
)
return struct
class ext4_xattr_entry(ext4_struct):
_fields_ = [
("e_name_len", c_ubyte), # 0x00
("e_name_index", c_ubyte), # 0x01
("e_value_offs", c_ushort), # 0x02
("e_value_inum", c_uint), # 0x04
("e_value_size", c_uint), # 0x08
("e_hash", c_uint) # 0x0C
# Variable length field "e_name" missing at 0x10
]
@classmethod
def _from_buffer_copy(cls, raw, offset=0, platform64=True):
# pylint: disable=no-self-argument
struct = ext4_xattr_entry.from_buffer_copy(raw, offset)
struct.e_name = raw[
offset + 0x10 : offset + 0x10 + struct.e_name_len
]
return struct
@property
def _size(self):
# 4-byte alignment
return 4 * ((sizeof(type(self)) + self.e_name_len + 3) // 4)
class ext4_xattr_header(ext4_struct):
_fields_ = [
("h_magic", c_uint), # 0x0, Must be 0xEA020000
("h_refcount", c_uint), # 0x4
("h_blocks", c_uint), # 0x8
("h_hash", c_uint), # 0xC
("h_checksum", c_uint), # 0x10
("h_reserved", c_uint * 3), # 0x14
]
class ext4_xattr_ibody_header(ext4_struct):
_fields_ = [("h_magic", c_uint)] # 0x0, Must be 0xEA020000
class InodeType:
UNKNOWN = 0x0 # Unknown file type
FILE = 0x1 # Regular file
DIRECTORY = 0x2 # Directory
CHARACTER_DEVICE = 0x3 # Character device
BLOCK_DEVICE = 0x4 # Block device
FIFO = 0x5 # FIFO
SOCKET = 0x6 # Socket
SYMBOLIC_LINK = 0x7 # Symbolic link
CHECKSUM = 0xDE # Checksum entry
class MappingEntry:
"""
Helper class: This class maps blkCnt file blocks
indexed by fileBlkIdx to the associated disk blocks indexed
by diskBlkIdx.
"""
def __init__(self, fileBlkIdx, diskBlkIdx, blkCnt=1):
"""
Initialize a MappingEntry instance with given fileBlkIdx,
diskBlkIdx and blkCnt.
"""
self.fileBlkIdx = fileBlkIdx
self.diskBlkIdx = diskBlkIdx
self.blkCnt = blkCnt
def __iter__(self):
"""
Can be used to convert an MappingEntry into a tuple
(fileBlkIdx, diskBlkIdx, blkCnt).
"""
yield self.fileBlkIdx
yield self.diskBlkIdx
yield self.blkCnt
def __repr__(self):
return "%s(%s, %s, %s)" % (
type(self).__name__,
self.fileBlkIdx,
self.diskBlkIdx,
self.blkCnt,
)
def copy(self):
return MappingEntry(
self.fileBlkIdx, self.diskBlkIdx, self.blkCnt
)
def create_mapping(*entries):
# pylint: disable=no-method-argument
# pylint: disable=no-self-argument
"""
Converts a list of 2-tuples
(diskBlkIdx, blkCnt) into a list of MappingEntry instances
"""
fileBlkIdx = 0
result = [None] * len(entries)
for i, entry in enumerate(entries):
diskBlkIdx, blkCnt = entry
result[i] = MappingEntry(fileBlkIdx, diskBlkIdx, blkCnt)
fileBlkIdx += blkCnt
return result
@classmethod
def optimize(cls, entries):
# pylint: disable=no-self-argument
"""
Sorts and stiches together a list of MappingEntry instances
"""
entries = list(entries)
entries.sort(key=lambda entry: entry.fileBlkIdx)
idx = 0
while idx < len(entries):
while (
(idx + 1 < len(entries))
and (
entries[idx].fileBlkIdx + entries[idx].blkCnt
== entries[idx + 1].fileBlkIdx
)
and (
entries[idx].diskBlkIdx + entries[idx].blkCnt
== entries[idx + 1].diskBlkIdx
)
):
tmp = entries.pop(idx + 1)
entries[idx].blkCnt += tmp.blkCnt
idx += 1
class Volume:
"""
Provides functionality for reading ext4 volumes
"""
ROOT_INODE = 2
def __init__(
self, stream, offset=0, ignoreFlag=False, ignoreMagic=False
):
"""
Initializes a new ext4 reader at a given offset in stream.
If ignoreMagic is True, no exception will be thrown,
when a structure with wrong magic number is found.
Analogously passing True to ignoreFlag suppresses Exception
caused by wrong flags.
"""
self.ignoreFlag = ignoreFlag
self.ignoreMagic = ignoreMagic
self.offset = offset
# Initial value needed for Volume.read_struct
self.platform64 = True
self.stream = stream
# Superblock
self.superblock = self.read_struct(ext4_superblock, 0x400)
self.platform64 = (
self.superblock.s_feature_incompat
& ext4_superblock.INCOMPAT_64BIT
) != 0
if not ignoreMagic and self.superblock.s_magic != 0xEF53:
raise MagicError(
(
"Invalid magic value in superblock: "
"0x%04X (expected 0xEF53)"
)
% self.superblock.s_magic
)
# Group descriptors
self.group_descriptors = [None] * (
self.superblock.s_inodes_count
// self.superblock.s_inodes_per_group
)
# First block after superblock
group_desc_table_offset = (
0x400 // self.block_size + 1
) * self.block_size
for group_desc_idx in xrange(len(self.group_descriptors)):
group_desc_offset = (
group_desc_table_offset
+ group_desc_idx * self.superblock.s_desc_size
)
self.group_descriptors[group_desc_idx] = self.read_struct(
ext4_group_descriptor, group_desc_offset
)
def __repr__(self):
return "%s(volume_name = %s, uuid = %s, last_mounted = %s)" % (
type(self).__name__,
self.superblock.s_volume_name,
self.uuid,
self.superblock.s_last_mounted,
)
@property
def block_size(self):
"""
Returns the volume's block size in bytes.
"""
return 1 << (10 + self.superblock.s_log_block_size)
def get_inode(self, inode_idx):
"""
Returns an Inode instance representing the inode specified
by its index inode_idx.
"""
group_idx, inode_table_entry_idx = self.get_inode_group(
inode_idx
)
inode_table_offset = (
self.group_descriptors[group_idx].bg_inode_table
* self.block_size
)
inode_offset = (
inode_table_offset
+ inode_table_entry_idx * self.superblock.s_inode_size
)
return Inode(self, inode_offset, inode_idx)
def get_inode_group(self, inode_idx):
"""
Returns a tuple (group_idx, inode_table_entry_idx)
"""
group_idx = (
inode_idx - 1
) // self.superblock.s_inodes_per_group
inode_table_entry_idx = (
inode_idx - 1
) % self.superblock.s_inodes_per_group
return (group_idx, inode_table_entry_idx)
def read(self, offset, byte_len):
"""
Returns byte_len bytes at offset within this volume.
"""
if self.offset + offset != self.stream.tell():
self.stream.seek(self.offset + offset, os.SEEK_SET)
return self.stream.read(byte_len)
def read_struct(self, structure, offset, platform64=None):
"""
Interprets the bytes at offset as structure and returns
the interpretd instance
"""
raw = self.read(offset, sizeof(structure))
if hasattr(structure, "_from_buffer_copy"):
return structure._from_buffer_copy(
raw,
platform64=platform64
if platform64 != None
else self.platform64,
)
else:
return structure.from_buffer_copy(raw)
@property
def root(self):
"""
Returns the volume's root inode
"""
return self.get_inode(Volume.ROOT_INODE)
@property
def uuid(self):
"""
Returns the volume's UUID in the format
XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX.
"""
uuid = self.superblock.s_uuid
uuid = [uuid[:4], uuid[4:6], uuid[6:8], uuid[8:10], uuid[10:]]
return "-".join(
"".join("%02X" % c for c in part) for part in uuid
)
class Inode:
"""
Provides functionality for parsing inodes and accessing raw data
"""
def __init__(self, volume, offset, inode_idx):
"""
Initializes a new inode parser at the specified offset
within the specified volume. file_type is the file type
of the inode as given by the directory entry
referring to this inode.
"""
self.inode_idx = inode_idx
self.offset = offset
self.volume = volume
self.inode = volume.read_struct(ext4_inode, offset)
def __len__(self):
"""
Returns the length in bytes of the content
referenced by this inode.
"""
return int(self.inode.i_size)
def __repr__(self):
if self.inode_idx != None:
return (
"%s(inode_idx = %s, offset = 0x%X, volume_uuid = %s"
) % (
type(self).__name__,
self.inode_idx,
self.offset,
self.volume.uuid,
)
else:
return "%s(offset = 0x%X, volume_uuid = %s)" % (
type(self).__name__,
self.offset,
self.volume.uuid,
)
def _parse_xattrs(self, raw_data, offset, prefix_override={}):
"""
Generator: Parses raw_data (bytes) as ext4_xattr_entry
structures and their referenced xattr values and yields
tuples (xattr_name, xattr_value) where xattr_name (str)
is the attribute name including its prefix and
xattr_value (bytes) is the raw attribute value.
raw_data must start with the first ext4_xattr_entry
structure and offset specifies the offset to the "block start"
for ext4_xattr_entry.e_value_offs.
prefix_overrides allows specifying attributes apart from
the default prefixes. The default prefix dictionary is
updated with prefix_overrides.
"""
prefixes = {
0: "",
1: "user.",
2: "system.posix_acl_access",
3: "system.posix_acl_default",
4: "trusted.",
6: "security.",
7: "system.",
8: "system.richacl",
}
prefixes.update(prefixes)
# Iterator over ext4_xattr_entry structures
i = 0
while i < len(raw_data):
xattr_entry = ext4_xattr_entry._from_buffer_copy(
raw_data, i, platform64=self.volume.platform64
)
if (
xattr_entry.e_name_len
| xattr_entry.e_name_index
| xattr_entry.e_value_offs
| xattr_entry.e_value_inum
) == 0:
# End of ext4_xattr_entry list
break
if not xattr_entry.e_name_index in prefixes:
raise Ext4Error(
"Unknown attribute prefix %d in inode %d"
% (xattr_entry.e_name_idx, self.inode_idx)
)
xattr_name = prefixes[
xattr_entry.e_name_index
] + xattr_entry.e_name.decode("iso-8859-2")
if xattr_entry.e_value_inum != 0:
# external xattr
xattr_inode = self.volume.get_inode(
xattr_entry.e_value_inum
)
if (
not self.volume.ignoreFlag
and (
xattr_inode.inode.i_flags
& ext4_inode.EXT4_EA_INODE_FL
)
!= 0
):
raise Ext4Error(
(
"Inode %d associated with the extended "
"attribute %s of inode %d is not marked as "
"large extended attribute value."
)
% (
xattr_inode.inode_idx,
xattr_name,
self.inode_idx,
)
)
# TODO Use xattr_entry.e_value_size or xattr_inode.inode.i_size?
xattr_value = xattr_inode.open_read().read()
else:
# internal xattr
start = xattr_entry.e_value_offs + offset
end = (
xattr_entry.e_value_offs
+ offset
+ xattr_entry.e_value_size
)
xattr_value = raw_data[start:end]
yield (xattr_name, xattr_value)
i += xattr_entry._size
def get_inode(self, *relative_path):
"""
Returns the inode specified by the path relative_path
(list of entry names) relative to this inode. "." and ".."
usually are supported too, however in special cases
(e.g. manually crafted volumes) they might not be supported
due to them being real on-disk directory entries that
might be missing or pointing somewhere else.
decode_name is directly passed to open_dir.
NOTE: Whitespaces will not be trimmed off the path's parts
and "\\0" and "\\0\\0" as well as b"\\0" and b"\\0\\0" are
seen as different names
(unless decode_name actually trims the name).
NOTE: Along the path file_type != FILETYPE_DIR will be
ignored, however i_flags will not be ignored.
"""
if not self.is_dir:
raise Ext4Error(
"Inode %d is not a directory" % self.inode_idx
)
current_inode = self
decode_name = None
for i, part in enumerate(relative_path):
if not self.volume.ignoreFlag and not current_inode.is_dir:
current_path = "/".join(relative_path[:i])
raise Ext4Error(
"%s (Inode %d) is not a directory."
% (current_path, self.inode_idx)
)
file_name, inode_idx, file_type = next(
filter(
lambda entry: entry[0] == part,
current_inode.open_dir(decode_name),
),
(None, None, None),
)
if inode_idx == None:
current_path = "/".join(relative_path[:i])
raise FileNotFoundError(
"%s not found in %s (Inode %d)"
% (part, current_path, current_inode.inode_idx)
)
current_inode = current_inode.volume.get_inode(inode_idx)
return current_inode
@property
def is_dir(self):
"""
Indicates whether the inode is marked as a directory.
"""
return (self.inode.i_mode & ext4_inode.S_IFDIR) != 0
@property
def is_file(self):
"""
Indicates whether the inode is marker as a regular file.
"""
return (self.inode.i_mode & ext4_inode.S_IFREG) != 0
@property
def is_in_use(self):
"""
Indicates whether the inode's associated bit
in the inode bitmap is set.
"""
group_idx, bitmap_bit = self.volume.get_inode_group(
self.inode_idx
)
inode_usage_bitmap_offset = (
self.volume.group_descriptors[group_idx].bg_inode_bitmap
* self.volume.block_size
)
inode_usage_byte = self.volume.read(
inode_usage_bitmap_offset + bitmap_bit // 8, 1
)[0]
return ((inode_usage_byte >> (7 - bitmap_bit % 8)) & 1) != 0
@property
def mode_str(self):
"""
Returns the inode's permissions in form of a unix string
(e.g. "-rwxrw-rw" or "drwxr-xr--").
"""
special_flag = lambda letter, execute, special: {
(False, False): "-",
(False, True): letter.upper(),
(True, False): "x",
(True, True): letter.lower(),
}[(execute, special)]
try:
device_type = {
ext4_inode.S_IFIFO: "p",
ext4_inode.S_IFCHR: "c",
ext4_inode.S_IFDIR: "d",
ext4_inode.S_IFBLK: "b",
ext4_inode.S_IFREG: "-",
ext4_inode.S_IFLNK: "l",
ext4_inode.S_IFSOCK: "s",
}[self.inode.i_mode & 0xF000]
except KeyError:
device_type = "?"
return "".join(
[
device_type,
"r"
if (self.inode.i_mode & ext4_inode.S_IRUSR) != 0
else "-",
"w"
if (self.inode.i_mode & ext4_inode.S_IWUSR) != 0
else "-",
special_flag(
"s",
(self.inode.i_mode & ext4_inode.S_IXUSR) != 0,
(self.inode.i_mode & ext4_inode.S_ISUID) != 0,
),
"r"
if (self.inode.i_mode & ext4_inode.S_IRGRP) != 0
else "-",
"w"
if (self.inode.i_mode & ext4_inode.S_IWGRP) != 0
else "-",
special_flag(
"s",
(self.inode.i_mode & ext4_inode.S_IXGRP) != 0,
(self.inode.i_mode & ext4_inode.S_ISGID) != 0,
),
"r"
if (self.inode.i_mode & ext4_inode.S_IROTH) != 0
else "-",
"w"
if (self.inode.i_mode & ext4_inode.S_IWOTH) != 0
else "-",
special_flag(
"t",
(self.inode.i_mode & ext4_inode.S_IXOTH) != 0,
(self.inode.i_mode & ext4_inode.S_ISVTX) != 0,
),
]
)
def open_dir(self, decode_name=None, path=None):
"""
Generator: Yields the directory entries as tuples
(decode_name(name), inode, file_type) in their on-disk order,
where name is the raw on-disk directory entry name (bytes).
file_type is one of the Inode.IT_* constants. For
special cases (e.g. invalid utf8 characters in entry names)
you can try a different decoder
(e.g. decode_name = lambda raw: raw).
Default of decode_name = lambda raw: raw.decode("utf8")
"""
# Parse args
if decode_name == None:
# decode_name = lambda raw: raw.decode("utf8")
decode_name = lambda raw: raw.decode("latin-1")
if not self.volume.ignoreFlag and not self.is_dir:
raise Ext4Error(
"Inode (%d) is not a directory (%s)"
% (self.inode_idx, path)
)
# Hash trees are compatible with linear arrays
if (self.inode.i_flags & ext4_inode.EXT4_INDEX_FL) != 0:
SysMgr.printWarn(
"hash trees are not implemented yet for %s" % path
)
return
# TODO: implement hash tree parser #
raise NotImplementedError(
"Hash trees are not implemented yet for %s" % path
)
# Read raw directory content
raw_data = self.open_read().read()
offset = 0
while offset < len(raw_data):
dirent = ext4_dir_entry_2._from_buffer_copy(
raw_data, offset, platform64=self.volume.platform64
)
if dirent.file_type != InodeType.CHECKSUM:
yield (
decode_name(dirent.name),
dirent.inode,
dirent.file_type,
)
offset += dirent.rec_len
def open_read(self):
"""
Returns an BlockReader instance for reading this inode's
raw content.
"""
if (self.inode.i_flags & ext4_inode.EXT4_EXTENTS_FL) != 0:
# Obtain mapping from extents
mapping = [] # List of MappingEntry instances
nodes = []
nodes.append(self.offset + ext4_inode.i_block.offset)
while nodes:
header_offset = nodes.pop(0)
header = self.volume.read_struct(
ext4_extent_header, header_offset
)
if (
not self.volume.ignoreMagic
and header.eh_magic != 0xF30A
):
raise MagicError(
(
"Invalid magic value in extent header at "
"offset 0x%X of inode %d: 0x%04X "
"(expected 0xF30A)"
)
% (
header_offset,
self.inode_idx,
header.eh_magic,
)
)
if header.eh_depth != 0:
indices = self.volume.read_struct(
ext4_extent_idx * header.eh_entries,
header_offset + sizeof(ext4_extent_header),
)
for idx in indices:
nodes.append(
idx.ei_leaf * self.volume.block_size
)
else:
extents = self.volume.read_struct(
ext4_extent * header.eh_entries,
header_offset + sizeof(ext4_extent_header),
)
for extent in extents:
mapping.append(
MappingEntry(
extent.ee_block,
extent.ee_start,
extent.ee_len,
)
)
MappingEntry.optimize(mapping)
return BlockReader(self.volume, len(self), mapping)
else:
# Inode uses inline data
i_block = self.volume.read(
self.offset + ext4_inode.i_block.offset,
ext4_inode.i_block.size,
)
return SysMgr.getPkg("io").BytesIO(
i_block[: self.inode.i_size]
)
def xattrs(
self,
check_inline=True,
check_block=True,
force_inline=False,
prefix_override={},
):
"""
Generator: Yields the inode's extended attributes as tuples
(name, value) in their on-disk order, where name (str)
is the on-disk attribute name including its resolved name
prefix and value (bytes) is the raw attribute value.
check_inline and check_block control where to read attributes
(the inode's inline data and/or the external data block
pointed to by i_file_acl) and if check_inline as well as
force_inline are set to True, the inode's inline data
will not be verified to contain actual extended attributes
and instead is just interpretd as such. prefix_overrides
is directly passed to Inode._parse_xattrs.
"""
# Inline xattrs
inline_data_offset = (
self.offset
+ ext4_inode.EXT2_GOOD_OLD_INODE_SIZE
+ self.inode.i_extra_isize
)
inline_data_length = (
self.offset
+ self.volume.superblock.s_inode_size
- inline_data_offset
)
if check_inline and inline_data_length > sizeof(
ext4_xattr_ibody_header
):
inline_data = self.volume.read(
inline_data_offset, inline_data_length
)
xattrs_header = ext4_xattr_ibody_header.from_buffer_copy(
inline_data
)
"""
TODO: Find way to detect inline xattrs without checking
the h_magic field to enable error detection with
the h_magic field.
"""
if force_inline or xattrs_header.h_magic == 0xEA020000:
# The ext4_xattr_entry following the header is aligned on a 4-byte boundary
offset = 4 * (
(sizeof(ext4_xattr_ibody_header) + 3) // 4
)
for xattr_name, xattr_value in self._parse_xattrs(
inline_data[offset:],
0,
prefix_override=prefix_override,
):
yield (xattr_name, xattr_value)
# xattr block(s)
if check_block and self.inode.i_file_acl != 0:
xattrs_block_start = (
self.inode.i_file_acl * self.volume.block_size
)
xattrs_block = self.volume.read(
xattrs_block_start, self.volume.block_size
)
xattrs_header = ext4_xattr_header.from_buffer_copy(
xattrs_block
)
if (
not self.volume.ignoreMagic
and xattrs_header.h_magic != 0xEA020000
):
raise MagicError(
(
"Invalid magic value in xattrs block header at "
"offset 0x%X of inode %d: 0x%X "
"(expected 0xEA020000)"
)
% (
xattrs_block_start,
self.inode_idx,
xattrs_header.h_magic,
)
)
if xattrs_header.h_blocks != 1:
raise Ext4Error(
"Invalid number of xattr blocks at offset "
"0x%X of inode %d: %d (expected 1)"
% (
xattrs_block_start,
self.inode_idx,
xattrs_header.h_blocks,
)
)
# The ext4_xattr_entry following the header is aligned on a 4-byte boundary
offset = 4 * ((sizeof(ext4_xattr_header) + 3) // 4)
for xattr_name, xattr_value in self._parse_xattrs(
xattrs_block[offset:],
-offset,
prefix_override=prefix_override,
):
yield (xattr_name, xattr_value)
class BlockReader:
"""
Maps disk blocks into a linear byte stream.
NOTE: This class does not implement buffering or caching.
"""
# OSError
EINVAL = 22
def __init__(self, volume, byte_size, block_map):
"""
Initializes a new block reader on the specified volume.
mapping must be a list of MappingEntry instances. If
you prefer a way to use 2-tuples (diskBlkIdx, blkCnt)
with inferred file_block_index entries, see
MappingEntry.create_mapping.
"""
self.byte_size = byte_size
self.volume = volume
self.cursor = 0
block_map = list(map(MappingEntry.copy, block_map))
# Optimize mapping (stich together)
MappingEntry.optimize(block_map)
self.block_map = block_map
def __repr__(self):
return (
"%s(byte_size = %s, block_map = %s, "
"volume_uuid = %s)"
% (
type(self).__name__,
self.byte_size,
self.block_map,
self.volume.uuid,
)
)
def get_block_mapping(self, fileBlkIdx):
"""
Returns the disk block index of the file block specified
by fileBlkIdx.
"""
diskBlkIdx = None
# Find disk block
for entry in self.block_map:
if (
entry.fileBlkIdx
<= fileBlkIdx
< entry.fileBlkIdx + entry.blkCnt
):
block_diff = fileBlkIdx - entry.fileBlkIdx
diskBlkIdx = entry.diskBlkIdx + block_diff
break
return diskBlkIdx
def read(self, byte_len=-1):
"""
Reades up to byte_len bytes from the block device beginning
at the cursor's current position. This operation will
not exceed the inode's size. If -1 is passed for byte_len,
the inode is read to the end.
"""
# Parse args
if byte_len < -1:
raise ValueError("byte_len must be non-negative or -1")
bytes_remaining = self.byte_size - self.cursor
byte_len = (
bytes_remaining
if byte_len == -1
else max(0, min(byte_len, bytes_remaining))
)
if byte_len == 0:
return b""
# Reading blocks
start_block_idx = self.cursor // self.volume.block_size
end_block_idx = (
self.cursor + byte_len - 1
) // self.volume.block_size
end_of_stream_check = byte_len
blocks = [
self.read_block(i)
for i in xrange(
start_block_idx, end_block_idx - start_block_idx + 1
)
]
startOffset = self.cursor % self.volume.block_size
if startOffset != 0:
blocks[0] = blocks[0][startOffset:]
byte_len = (
byte_len + startOffset - self.volume.block_size - 1
) % self.volume.block_size + 1
blocks[-1] = blocks[-1][:byte_len]
result = b"".join(blocks)
# Check read
if len(result) != end_of_stream_check:
raise EndOfStreamError(
(
"The volume's underlying stream ended "
"%s bytes before EOF."
)
% (UtilMgr.convNum(byte_len - len(result)))
)
self.cursor += len(result)
return result
def read_block(self, fileBlkIdx):
"""
Reads one block from disk
(return a zero-block if the file block is not mapped)
"""
diskBlkIdx = self.get_block_mapping(fileBlkIdx)
if diskBlkIdx != None:
return self.volume.read(
diskBlkIdx * self.volume.block_size,
self.volume.block_size,
)
else:
return bytes([0] * self.volume.block_size)
def seek(self, seek, seek_mode=os.SEEK_SET):
"""
Moves the internal cursor along the file
(not the disk) and behaves like BufferedReader.seek
"""
if seek_mode == os.SEEK_CUR:
seek += self.cursor
elif seek_mode == os.SEEK_END:
seek += self.byte_size
elif seek_mode == os.SEEK_SET:
seek += 0
if seek < 0:
# Exception behavior copied from IOBase.seek
raise OSError(BlockReader.EINVAL, "Invalid argument")
self.cursor = seek
return seek
def tell(self):
"""
Returns the internal cursor's current file offset.
"""
return self.cursor
# open target file #
try:
self.fd = open(path, "rb")
except SystemExit:
sys.exit(0)
except:
SysMgr.printWarn("failed to open %s" % path, reason=True)
raise Exception("open failure")
# init volume object #
try:
self.volume = Volume(self.fd)
except SystemExit:
sys.exit(0)
except:
SysMgr.printWarn(
"failed to init EXT4 object for %s'" % path, reason=True
)
# check volume object #
if not self.volume:
raise Exception("volume failure")
def getInodeInfo(self, inode=None, path=None):
if not inode and not path:
SysMgr.printErr("no input for inode or path to get file meta info")
return None
if inode:
inode = long(inode)
inodeObj = self.volume.get_inode(inode)
return inodeObj
if path:
parent = self.volume.root
for item in path.split("/"):
if not item:
continue
parent = parent.get_inode(item)
return parent
def getInodeList(self, start=None, path=None, filters=[], verb=False):
# define traverse function #
def _traverseItems(self, start, path, filters, verb):
if start:
if type(start) is str:
path = start.strip()
parent = self.volume.root
for item in start.split("/"):
if not item:
continue
parent = parent.get_inode(item)
start = parent
else:
start = self.volume.root
path = "/"
# print progress #
UtilMgr.printProgress()
# open directory #
FILE_TYPE = Ext4Analyzer.FILE_TYPE
try:
dirnode = start.open_dir(path=path)
if not dirnode:
self.failDirList.setdefault(path, None)
except SystemExit:
sys.exit(0)
except:
self.failDirList.setdefault(path, None)
SysMgr.printWarn("failed to open '%s' directory" % None, True)
return
# traverse all items #
for fname, inode, ftype in dirnode:
if fname in (".", ".."):
continue
elif inode in self.inodeList:
continue
# define attribute #
ftype = FILE_TYPE[ftype] if ftype in FILE_TYPE else "?"
inodeObj = self.volume.get_inode(inode)
fpath = os.path.join(path, fname)
# check condition #
if not UtilMgr.isValidStr(
str(inode), filters
) and not UtilMgr.isValidStr(fpath, filters):
pass
else:
self.inodeList[inode] = {
"name": fname,
"type": ftype,
"size": len(inodeObj),
"path": path,
}
if verb:
SysMgr.printWarn(
"%s [inode: %s] [type: %s] [size: %s]"
% (
fpath,
inode,
ftype,
UtilMgr.convSize2Unit(len(inodeObj)),
),
always=True,
newline=False,
)
if ftype == "dir":
_traverseItems(self, inodeObj, fpath, filters, verb)
continue
# start traversing all items #
_traverseItems(self, start, path, filters, verb)
# return inode list #
return self.inodeList
'''
class GlMgr(object):
"""Manager for GL"""
instance = None
@staticmethod
def init():
SysMgr.importPkgItems("ctypes")
try:
# load libglesobj library #
if not SysMgr.libglesObj:
SysMgr.libglesObj = SysMgr.loadLib(SysMgr.libglesPath)
except:
SysMgr.printErr("failed to load GLES object")
sys.exit(-1)
gl = GlMgr.instance = SysMgr.libglesObj
gl.glActiveShaderProgram.argtypes = [c_uint32, c_uint32]
gl.glActiveShaderProgram.restype = None
gl.glActiveTexture.argtypes = [c_uint]
gl.glActiveTexture.restype = None
gl.glAttachShader.argtypes = [c_uint32, c_uint32]
gl.glAttachShader.restype = None
gl.glBeginQuery.argtypes = [c_uint, c_uint32]
gl.glBeginQuery.restype = None
gl.glBeginTransformFeedback.argtypes = [c_uint]
gl.glBeginTransformFeedback.restype = None
gl.glBindAttribLocation.argtypes = [
c_uint32,
c_uint32,
POINTER(c_char),
]
gl.glBindAttribLocation.restype = None
gl.glBindBuffer.argtypes = [c_uint, c_uint32]
gl.glBindBuffer.restype = None
gl.glBindBufferBase.argtypes = [c_uint, c_uint32, c_uint32]
gl.glBindBufferBase.restype = None
gl.glBindBufferRange.argtypes = [
c_uint,
c_uint32,
c_uint32,
c_size_t,
c_ssize_t,
]
gl.glBindBufferRange.restype = None
gl.glBindFramebuffer.argtypes = [c_uint, c_uint32]
gl.glBindFramebuffer.restype = None
gl.glBindImageTexture.argtypes = [
c_uint32,
c_uint32,
c_int32,
c_ubyte,
c_int32,
c_uint,
c_uint,
]
gl.glBindImageTexture.restype = None
gl.glBindProgramPipeline.argtypes = [c_uint32]
gl.glBindProgramPipeline.restype = None
gl.glBindRenderbuffer.argtypes = [c_uint, c_uint32]
gl.glBindRenderbuffer.restype = None
gl.glBindSampler.argtypes = [c_uint32, c_uint32]
gl.glBindSampler.restype = None
gl.glBindTexture.argtypes = [c_uint, c_uint]
gl.glBindTexture.restype = None
gl.glBindTransformFeedback.argtypes = [c_uint, c_uint32]
gl.glBindTransformFeedback.restype = None
gl.glBindVertexArray.argtypes = [c_uint32]
gl.glBindVertexArray.restype = None
gl.glBindVertexBuffer.argtypes = [
c_uint32,
c_uint32,
c_size_t,
c_size_t,
]
gl.glBindVertexBuffer.restype = None
gl.glBlendColor.argtypes = [c_float, c_float, c_float, c_float]
gl.glBlendColor.restype = None
gl.glBlendEquation.argtypes = [c_uint]
gl.glBlendEquation.restype = None
gl.glBlendEquationSeparate.argtypes = [c_uint, c_uint]
gl.glBlendEquationSeparate.restype = None
gl.glBlendEquationSeparatei.argtypes = [c_uint32, c_uint, c_uint]
gl.glBlendEquationSeparatei.restype = None
gl.glBlendEquationi.argtypes = [c_uint32, c_uint]
gl.glBlendEquationi.restype = None
gl.glBlendFunc.argtypes = [c_uint, c_uint]
gl.glBlendFunc.restype = None
gl.glBlendFuncSeparate.argtypes = [c_uint, c_uint, c_uint, c_uint]
gl.glBlendFuncSeparate.restype = None
gl.glBlendFuncSeparatei.argtypes = [
c_uint32,
c_uint,
c_uint,
c_uint,
c_uint,
]
gl.glBlendFuncSeparatei.restype = None
gl.glBlendFunci.argtypes = [c_uint32, c_uint, c_uint]
gl.glBlendFunci.restype = None
gl.glBlitFramebuffer.argtypes = [
c_int32,
c_int32,
c_int32,
c_int32,
c_int32,
c_int32,
c_int32,
c_int32,
c_uint,
c_uint,
]
gl.glBlitFramebuffer.restype = None
gl.glBufferData.argtypes = [c_uint, c_ssize_t, c_void_p, c_uint]
gl.glBufferData.restype = None
gl.glBufferSubData.argtypes = [c_uint, c_size_t, c_ssize_t, c_void_p]
gl.glBufferSubData.restype = None
gl.glCheckFramebufferStatus.argtypes = [c_uint]
gl.glCheckFramebufferStatus.restype = c_uint
gl.glClear.argtypes = [c_uint]
gl.glClear.restype = None
gl.glClearBufferfi.argtypes = [c_uint, c_int, c_float, c_int32]
gl.glClearBufferfi.restype = None
gl.glClearBufferfv.argtypes = [c_uint, c_int, POINTER(c_float)]
gl.glClearBufferfv.restype = None
gl.glClearBufferiv.argtypes = [c_uint, c_int, POINTER(c_int32)]
gl.glClearBufferiv.restype = None
gl.glClearBufferuiv.argtypes = [c_uint, c_int, POINTER(c_uint32)]
gl.glClearBufferuiv.restype = None
gl.glClearColor.argtypes = [c_float, c_float, c_float, c_float]
gl.glClearColor.restype = None
gl.glClearDepthf.argtypes = [c_float]
gl.glClearDepthf.restype = None
gl.glClearStencil.argtypes = [c_int]
gl.glClearStencil.restype = None
gl.glColorMask.argtypes = [c_ubyte, c_ubyte, c_ubyte, c_ubyte]
gl.glColorMask.restype = None
gl.glColorMaski.argtypes = [
c_uint32,
c_ubyte,
c_ubyte,
c_ubyte,
c_ubyte,
]
gl.glColorMaski.restype = None
gl.glCompileShader.argtypes = [c_uint32]
gl.glCompileShader.restype = None
gl.glCompressedTexImage2D.argtypes = [
c_uint,
c_long,
c_uint,
c_size_t,
c_size_t,
c_long,
c_size_t,
c_void_p,
]
gl.glCompressedTexImage2D.restype = None
gl.glCompressedTexImage3D.argtypes = [
c_uint,
c_long,
c_uint,
c_size_t,
c_size_t,
c_size_t,
c_long,
c_size_t,
c_void_p,
]
gl.glCompressedTexImage3D.restype = None
gl.glCompressedTexSubImage2D.argtypes = [
c_uint,
c_long,
c_long,
c_long,
c_size_t,
c_size_t,
c_uint,
c_size_t,
c_void_p,
]
gl.glCompressedTexSubImage2D.restype = None
gl.glCompressedTexSubImage3D.argtypes = [
c_uint,
c_long,
c_long,
c_long,
c_long,
c_size_t,
c_size_t,
c_size_t,
c_uint,
c_size_t,
c_void_p,
]
gl.glCompressedTexSubImage3D.restype = None
gl.glCopyBufferSubData.argtypes = [
c_uint,
c_uint,
c_size_t,
c_size_t,
c_ssize_t,
]
gl.glCopyBufferSubData.restype = None
gl.glCopyImageSubData.argtypes = [
c_uint32,
c_uint,
c_int32,
c_int32,
c_int32,
c_int32,
c_uint32,
c_uint,
c_int32,
c_int32,
c_int32,
c_int32,
c_size_t,
c_size_t,
c_size_t,
]
gl.glCopyImageSubData.restype = None
gl.glCopyTexImage2D.argtypes = [
c_uint,
c_long,
c_uint,
c_int,
c_int,
c_size_t,
c_size_t,
c_long,
]
gl.glCopyTexImage2D.restype = None
gl.glCopyTexSubImage2D.argtypes = [
c_uint,
c_long,
c_long,
c_long,
c_int,
c_int,
c_size_t,
c_size_t,
]
gl.glCopyTexSubImage2D.restype = None
gl.glCopyTexSubImage3D.argtypes = [
c_uint,
c_long,
c_long,
c_long,
c_long,
c_int,
c_int,
c_size_t,
c_size_t,
]
gl.glCopyTexSubImage3D.restype = None
gl.glCreateProgram.argtypes = None
gl.glCreateProgram.restype = c_uint32
gl.glCreateShader.argtypes = [c_uint]
gl.glCreateShader.restype = c_uint32
gl.glCreateShaderProgramv.argtypes = [
c_uint,
c_size_t,
POINTER(c_char_p),
]
gl.glCreateShaderProgramv.restype = c_uint32
gl.glCullFace.argtypes = [c_uint]
gl.glCullFace.restype = None
gl.glDebugMessageControl.argtypes = [
c_uint,
c_uint,
c_uint,
c_size_t,
POINTER(c_uint32),
c_ubyte,
]
gl.glDebugMessageControl.restype = None
gl.glDebugMessageInsert.argtypes = [
c_uint,
c_uint,
c_uint32,
c_uint,
c_size_t,
POINTER(c_char),
]
gl.glDebugMessageInsert.restype = None
gl.glDeleteBuffers.argtypes = [c_size_t, POINTER(c_ulong)]
gl.glDeleteBuffers.restype = None
gl.glDeleteFramebuffers.argtypes = [c_size_t, POINTER(c_uint32)]
gl.glDeleteFramebuffers.restype = None
gl.glDeleteProgram.argtypes = [c_uint32]
gl.glDeleteProgram.restype = None
gl.glDeleteProgramPipelines.argtypes = [c_size_t, POINTER(c_uint32)]
gl.glDeleteProgramPipelines.restype = None
gl.glDeleteQueries.argtypes = [c_size_t, POINTER(c_uint32)]
gl.glDeleteQueries.restype = None
gl.glDeleteRenderbuffers.argtypes = [c_size_t, POINTER(c_uint32)]
gl.glDeleteRenderbuffers.restype = None
gl.glDeleteSamplers.argtypes = [c_size_t, POINTER(c_uint32)]
gl.glDeleteSamplers.restype = None
gl.glDeleteShader.argtypes = [c_uint32]
gl.glDeleteShader.restype = None
gl.glDeleteTextures.argtypes = [c_size_t, POINTER(c_uint)]
gl.glDeleteTextures.restype = None
gl.glDeleteTransformFeedbacks.argtypes = [c_size_t, POINTER(c_uint32)]
gl.glDeleteTransformFeedbacks.restype = None
gl.glDeleteVertexArrays.argtypes = [c_size_t, POINTER(c_uint32)]
gl.glDeleteVertexArrays.restype = None
gl.glDepthFunc.argtypes = [c_uint]
gl.glDepthFunc.restype = None
gl.glDepthMask.argtypes = [c_ubyte]
gl.glDepthMask.restype = None
gl.glDepthRangef.argtypes = [c_float, c_float]
gl.glDepthRangef.restype = None
gl.glDetachShader.argtypes = [c_uint32, c_uint32]
gl.glDetachShader.restype = None
gl.glDisable.argtypes = [c_uint]
gl.glDisable.restype = None
gl.glDisableVertexAttribArray.argtypes = [c_uint32]
gl.glDisableVertexAttribArray.restype = None
gl.glDisablei.argtypes = [c_uint, c_uint32]
gl.glDisablei.restype = None
gl.glDispatchCompute.argtypes = [c_uint32, c_uint32, c_uint32]
gl.glDispatchCompute.restype = None
gl.glDispatchComputeIndirect.argtypes = [c_size_t]
gl.glDispatchComputeIndirect.restype = None
gl.glDrawArrays.argtypes = [c_uint, c_int32, c_size_t]
gl.glDrawArrays.restype = None
gl.glDrawArraysIndirect.argtypes = [c_uint, c_void_p]
gl.glDrawArraysIndirect.restype = None
gl.glDrawArraysInstanced.argtypes = [
c_uint,
c_int32,
c_size_t,
c_size_t,
]
gl.glDrawArraysInstanced.restype = None
gl.glDrawBuffers.argtypes = [c_size_t, POINTER(c_uint)]
gl.glDrawBuffers.restype = None
gl.glDrawElements.argtypes = [c_uint, c_size_t, c_uint, c_void_p]
gl.glDrawElements.restype = None
gl.glDrawElementsBaseVertex.argtypes = [
c_uint,
c_size_t,
c_uint,
c_void_p,
c_int32,
]
gl.glDrawElementsBaseVertex.restype = None
gl.glDrawElementsIndirect.argtypes = [c_uint, c_uint, c_void_p]
gl.glDrawElementsIndirect.restype = None
gl.glDrawElementsInstanced.argtypes = [
c_uint,
c_size_t,
c_uint,
c_void_p,
c_size_t,
]
gl.glDrawElementsInstanced.restype = None
gl.glDrawElementsInstancedBaseVertex.argtypes = [
c_uint,
c_size_t,
c_uint,
c_void_p,
c_size_t,
c_int32,
]
gl.glDrawElementsInstancedBaseVertex.restype = None
gl.glDrawRangeElements.argtypes = [
c_uint,
c_uint32,
c_uint32,
c_size_t,
c_uint,
c_void_p,
]
gl.glDrawRangeElements.restype = None
gl.glDrawRangeElementsBaseVertex.argtypes = [
c_uint,
c_uint32,
c_uint32,
c_size_t,
c_uint,
c_void_p,
c_int32,
]
gl.glDrawRangeElementsBaseVertex.restype = None
gl.glEnable.argtypes = [c_uint]
gl.glEnable.restype = None
gl.glEnableVertexAttribArray.argtypes = [c_uint32]
gl.glEnableVertexAttribArray.restype = None
gl.glEnablei.argtypes = [c_uint, c_uint32]
gl.glEnablei.restype = None
gl.glEndQuery.argtypes = [c_uint]
gl.glEndQuery.restype = None
gl.glEndTransformFeedback.argtypes = None
gl.glEndTransformFeedback.restype = None
gl.glFinish.argtypes = None
gl.glFinish.restype = None
gl.glFlush.argtypes = None
gl.glFlush.restype = None
gl.glFlushMappedBufferRange.argtypes = [c_uint, c_size_t, c_ssize_t]
gl.glFlushMappedBufferRange.restype = None
gl.glFramebufferParameteri.argtypes = [c_uint, c_uint, c_int32]
gl.glFramebufferParameteri.restype = None
gl.glFramebufferRenderbuffer.argtypes = [
c_uint,
c_uint,
c_uint,
c_uint32,
]
gl.glFramebufferRenderbuffer.restype = None
gl.glFramebufferTexture.argtypes = [c_uint, c_uint, c_uint32, c_int32]
gl.glFramebufferTexture.restype = None
gl.glFramebufferTexture2D.argtypes = [
c_uint,
c_uint,
c_uint,
c_uint32,
c_int32,
]
gl.glFramebufferTexture2D.restype = None
gl.glFramebufferTextureLayer.argtypes = [
c_uint,
c_uint,
c_uint,
c_long,
c_long,
]
gl.glFramebufferTextureLayer.restype = None
gl.glFrontFace.argtypes = [c_uint]
gl.glFrontFace.restype = None
gl.glGenBuffers.argtypes = [c_size_t, POINTER(c_uint32)]
gl.glGenBuffers.restype = None
gl.glGenFramebuffers.argtypes = [c_size_t, POINTER(c_uint32)]
gl.glGenFramebuffers.restype = None
gl.glGenProgramPipelines.argtypes = [c_size_t, POINTER(c_uint32)]
gl.glGenProgramPipelines.restype = None
gl.glGenQueries.argtypes = [c_size_t, POINTER(c_uint32)]
gl.glGenQueries.restype = None
gl.glGenRenderbuffers.argtypes = [c_size_t, POINTER(c_uint32)]
gl.glGenRenderbuffers.restype = None
gl.glGenSamplers.argtypes = [c_size_t, POINTER(c_uint32)]
gl.glGenSamplers.restype = None
gl.glGenTextures.argtypes = [c_size_t, POINTER(c_uint)]
gl.glGenTextures.restype = None
gl.glGenTransformFeedbacks.argtypes = [c_size_t, POINTER(c_uint32)]
gl.glGenTransformFeedbacks.restype = None
gl.glGenVertexArrays.argtypes = [c_size_t, POINTER(c_uint32)]
gl.glGenVertexArrays.restype = None
gl.glGenerateMipmap.argtypes = [c_uint]
gl.glGenerateMipmap.restype = None
gl.glGetActiveAttrib.argtypes = [
c_uint32,
c_uint32,
c_size_t,
POINTER(c_size_t),
POINTER(c_int32),
POINTER(c_uint),
POINTER(c_char),
]
gl.glGetActiveAttrib.restype = None
gl.glGetActiveUniform.argtypes = [
c_uint32,
c_uint32,
c_size_t,
POINTER(c_size_t),
POINTER(c_int32),
POINTER(c_uint),
POINTER(c_char),
]
gl.glGetActiveUniform.restype = None
gl.glGetActiveUniformBlockName.argtypes = [
c_uint32,
c_uint32,
c_size_t,
POINTER(c_size_t),
POINTER(c_char),
]
gl.glGetActiveUniformBlockName.restype = None
gl.glGetActiveUniformBlockiv.argtypes = [
c_uint32,
c_uint32,
c_uint,
POINTER(c_int32),
]
gl.glGetActiveUniformBlockiv.restype = None
gl.glGetActiveUniformsiv.argtypes = [
c_uint32,
c_size_t,
POINTER(c_uint32),
c_uint,
POINTER(c_int32),
]
gl.glGetActiveUniformsiv.restype = None
gl.glGetAttachedShaders.argtypes = [
c_uint32,
c_size_t,
POINTER(c_size_t),
POINTER(c_uint32),
]
gl.glGetAttachedShaders.restype = None
gl.glGetAttribLocation.argtypes = [c_uint32, POINTER(c_char)]
gl.glGetAttribLocation.restype = c_int32
gl.glGetBooleanv.argtypes = [c_uint, POINTER(c_ubyte)]
gl.glGetBooleanv.restype = None
gl.glGetBufferParameteri64v.argtypes = [
c_uint,
c_uint,
POINTER(c_int64),
]
gl.glGetBufferParameteri64v.restype = None
gl.glGetBufferParameteriv.argtypes = [c_uint, c_uint, POINTER(c_int32)]
gl.glGetBufferParameteriv.restype = None
gl.glGetBufferPointerv.argtypes = [c_uint, c_uint, POINTER(c_void_p)]
gl.glGetBufferPointerv.restype = None
gl.glGetDebugMessageLog.argtypes = [
c_uint32,
c_size_t,
POINTER(c_uint),
POINTER(c_uint),
POINTER(c_uint32),
POINTER(c_uint),
POINTER(c_size_t),
POINTER(c_char),
]
gl.glGetDebugMessageLog.restype = c_uint32
gl.glGetError.argtypes = None
gl.glGetError.restype = c_uint
gl.glGetFloatv.argtypes = [c_uint, POINTER(c_float)]
gl.glGetFloatv.restype = None
gl.glGetFragDataLocation.argtypes = [c_uint32, POINTER(c_char)]
gl.glGetFragDataLocation.restype = c_int32
gl.glGetFramebufferAttachmentParameteriv.argtypes = [
c_uint,
c_uint,
c_uint,
POINTER(c_int32),
]
gl.glGetFramebufferAttachmentParameteriv.restype = None
gl.glGetFramebufferParameteriv.argtypes = [
c_uint,
c_uint,
POINTER(c_int32),
]
gl.glGetFramebufferParameteriv.restype = None
gl.glGetInteger64v.argtypes = [c_uint, POINTER(c_int64)]
gl.glGetInteger64v.restype = None
gl.glGetIntegerv.argtypes = [c_uint, POINTER(c_int32)]
gl.glGetIntegerv.restype = None
gl.glGetInternalformativ.argtypes = [
c_uint,
c_uint,
c_uint,
c_size_t,
POINTER(c_int32),
]
gl.glGetInternalformativ.restype = None
gl.glGetMultisamplefv.argtypes = [c_uint, c_uint32, POINTER(c_float)]
gl.glGetMultisamplefv.restype = None
gl.glGetObjectLabel.argtypes = [
c_uint,
c_uint32,
c_size_t,
POINTER(c_size_t),
POINTER(c_char),
]
gl.glGetObjectLabel.restype = None
gl.glGetObjectPtrLabel.argtypes = [
c_void_p,
c_size_t,
POINTER(c_size_t),
POINTER(c_char),
]
gl.glGetObjectPtrLabel.restype = None
gl.glGetPointerv.argtypes = [c_uint, POINTER(c_void_p)]
gl.glGetPointerv.restype = None
gl.glGetProgramBinary.argtypes = [
c_uint32,
c_size_t,
POINTER(c_size_t),
POINTER(c_uint),
c_void_p,
]
gl.glGetProgramBinary.restype = None
gl.glGetProgramInfoLog.argtypes = [
c_uint32,
c_size_t,
POINTER(c_size_t),
POINTER(c_char),
]
gl.glGetProgramInfoLog.restype = None
gl.glGetProgramInterfaceiv.argtypes = [
c_uint32,
c_uint,
c_uint,
POINTER(c_int32),
]
gl.glGetProgramInterfaceiv.restype = None
gl.glGetProgramPipelineInfoLog.argtypes = [
c_uint32,
c_size_t,
POINTER(c_size_t),
POINTER(c_char),
]
gl.glGetProgramPipelineInfoLog.restype = None
gl.glGetProgramPipelineiv.argtypes = [
c_uint32,
c_uint,
POINTER(c_int32),
]
gl.glGetProgramPipelineiv.restype = None
gl.glGetProgramResourceIndex.argtypes = [
c_uint32,
c_uint,
POINTER(c_char),
]
gl.glGetProgramResourceIndex.restype = c_uint32
gl.glGetProgramResourceLocation.argtypes = [
c_uint32,
c_uint,
POINTER(c_char),
]
gl.glGetProgramResourceLocation.restype = c_int32
gl.glGetProgramResourceName.argtypes = [
c_uint32,
c_uint,
c_uint32,
c_size_t,
POINTER(c_size_t),
POINTER(c_char),
]
gl.glGetProgramResourceName.restype = None
gl.glGetProgramResourceiv.argtypes = [
c_uint32,
c_uint,
c_uint32,
c_size_t,
POINTER(c_uint),
c_size_t,
POINTER(c_size_t),
POINTER(c_int32),
]
gl.glGetProgramResourceiv.restype = None
gl.glGetProgramiv.argtypes = [c_uint32, c_uint, POINTER(c_int32)]
gl.glGetProgramiv.restype = None
gl.glGetQueryObjectuiv.argtypes = [c_uint32, c_uint, POINTER(c_uint32)]
gl.glGetQueryObjectuiv.restype = None
gl.glGetQueryiv.argtypes = [c_uint, c_uint, POINTER(c_int32)]
gl.glGetQueryiv.restype = None
gl.glGetRenderbufferParameteriv.argtypes = [
c_uint,
c_uint,
POINTER(c_int32),
]
gl.glGetRenderbufferParameteriv.restype = None
gl.glGetSamplerParameterIiv.argtypes = [
c_uint32,
c_uint,
POINTER(c_int32),
]
gl.glGetSamplerParameterIiv.restype = None
gl.glGetSamplerParameterIuiv.argtypes = [
c_uint32,
c_uint,
POINTER(c_uint32),
]
gl.glGetSamplerParameterIuiv.restype = None
gl.glGetSamplerParameterfv.argtypes = [
c_uint32,
c_uint,
POINTER(c_float),
]
gl.glGetSamplerParameterfv.restype = None
gl.glGetSamplerParameteriv.argtypes = [
c_uint32,
c_uint,
POINTER(c_int32),
]
gl.glGetSamplerParameteriv.restype = None
gl.glGetShaderInfoLog.argtypes = [
c_uint32,
c_size_t,
POINTER(c_size_t),
POINTER(c_char),
]
gl.glGetShaderInfoLog.restype = None
gl.glGetShaderPrecisionFormat.argtypes = [
c_uint,
c_uint,
POINTER(c_int32),
POINTER(c_int32),
]
gl.glGetShaderPrecisionFormat.restype = None
gl.glGetShaderSource.argtypes = [
c_uint32,
c_size_t,
POINTER(c_size_t),
POINTER(c_char),
]
gl.glGetShaderSource.restype = None
gl.glGetShaderiv.argtypes = [c_uint32, c_uint, POINTER(c_int32)]
gl.glGetShaderiv.restype = None
gl.glGetString.argtypes = [c_uint]
gl.glGetString.restype = c_char_p
gl.glGetStringi.argtypes = [c_uint, c_uint32]
gl.glGetStringi.restype = c_char_p
gl.glGetTexLevelParameterfv.argtypes = [
c_uint,
c_long,
c_uint,
POINTER(c_float),
]
gl.glGetTexLevelParameterfv.restype = None
gl.glGetTexLevelParameteriv.argtypes = [
c_uint,
c_long,
c_uint,
POINTER(c_int32),
]
gl.glGetTexLevelParameteriv.restype = None
gl.glGetTexParameterIiv.argtypes = [c_uint, c_uint, POINTER(c_int32)]
gl.glGetTexParameterIiv.restype = None
gl.glGetTexParameterIuiv.argtypes = [c_uint, c_uint, POINTER(c_uint32)]
gl.glGetTexParameterIuiv.restype = None
gl.glGetTexParameterfv.argtypes = [c_uint, c_uint, POINTER(c_float)]
gl.glGetTexParameterfv.restype = None
gl.glGetTexParameteriv.argtypes = [c_uint, c_uint, POINTER(c_int32)]
gl.glGetTexParameteriv.restype = None
gl.glGetTransformFeedbackVarying.argtypes = [
c_uint32,
c_uint32,
c_size_t,
POINTER(c_size_t),
POINTER(c_size_t),
POINTER(c_uint),
POINTER(c_char),
]
gl.glGetTransformFeedbackVarying.restype = None
gl.glGetUniformBlockIndex.argtypes = [c_uint32, POINTER(c_char)]
gl.glGetUniformBlockIndex.restype = c_uint32
gl.glGetUniformIndices.argtypes = [
c_uint32,
c_size_t,
POINTER(c_char_p),
POINTER(c_uint32),
]
gl.glGetUniformIndices.restype = None
gl.glGetUniformLocation.argtypes = [c_uint32, POINTER(c_char)]
gl.glGetUniformLocation.restype = c_int32
gl.glGetUniformfv.argtypes = [c_uint32, c_int32, POINTER(c_float)]
gl.glGetUniformfv.restype = None
gl.glGetUniformiv.argtypes = [c_uint32, c_int32, POINTER(c_int32)]
gl.glGetUniformiv.restype = None
gl.glGetUniformuiv.argtypes = [c_uint32, c_int32, POINTER(c_uint32)]
gl.glGetUniformuiv.restype = None
gl.glGetVertexAttribIiv.argtypes = [c_uint32, c_uint, POINTER(c_int32)]
gl.glGetVertexAttribIiv.restype = None
gl.glGetVertexAttribIuiv.argtypes = [
c_uint32,
c_uint,
POINTER(c_uint32),
]
gl.glGetVertexAttribIuiv.restype = None
gl.glGetVertexAttribPointerv.argtypes = [
c_uint32,
c_uint,
POINTER(c_void_p),
]
gl.glGetVertexAttribPointerv.restype = None
gl.glGetVertexAttribfv.argtypes = [c_uint32, c_uint, POINTER(c_float)]
gl.glGetVertexAttribfv.restype = None
gl.glGetVertexAttribiv.argtypes = [c_uint32, c_uint, POINTER(c_int32)]
gl.glGetVertexAttribiv.restype = None
gl.glHint.argtypes = [c_uint, c_uint]
gl.glHint.restype = None
gl.glInvalidateFramebuffer.argtypes = [
c_uint,
c_size_t,
POINTER(c_uint),
]
gl.glInvalidateFramebuffer.restype = None
gl.glInvalidateSubFramebuffer.argtypes = [
c_uint,
c_size_t,
POINTER(c_uint),
c_int32,
c_int32,
c_size_t,
c_size_t,
]
gl.glInvalidateSubFramebuffer.restype = None
gl.glIsBuffer.argtypes = [c_uint32]
gl.glIsBuffer.restype = c_ubyte
gl.glIsEnabled.argtypes = [c_uint]
gl.glIsEnabled.restype = c_ubyte
gl.glIsEnabledi.argtypes = [c_uint, c_uint32]
gl.glIsEnabledi.restype = c_ubyte
gl.glIsFramebuffer.argtypes = [c_uint32]
gl.glIsFramebuffer.restype = c_ubyte
gl.glIsProgram.argtypes = [c_uint32]
gl.glIsProgram.restype = c_ubyte
gl.glIsProgramPipeline.argtypes = [c_uint32]
gl.glIsProgramPipeline.restype = c_ubyte
gl.glIsQuery.argtypes = [c_uint32]
gl.glIsQuery.restype = c_ubyte
gl.glIsRenderbuffer.argtypes = [c_uint32]
gl.glIsRenderbuffer.restype = c_ubyte
gl.glIsSampler.argtypes = [c_uint32]
gl.glIsSampler.restype = c_ubyte
gl.glIsShader.argtypes = [c_uint32]
gl.glIsShader.restype = c_ubyte
gl.glIsTexture.argtypes = [c_uint]
gl.glIsTexture.restype = c_ubyte
gl.glIsTransformFeedback.argtypes = [c_uint32]
gl.glIsTransformFeedback.restype = c_ubyte
gl.glIsVertexArray.argtypes = [c_uint32]
gl.glIsVertexArray.restype = c_ubyte
gl.glLineWidth.argtypes = [c_float]
gl.glLineWidth.restype = None
gl.glLinkProgram.argtypes = [c_uint32]
gl.glLinkProgram.restype = None
gl.glMapBufferRange.argtypes = [c_uint, c_size_t, c_ssize_t, c_uint]
gl.glMapBufferRange.restype = c_void_p
gl.glMemoryBarrier.argtypes = [c_uint]
gl.glMemoryBarrier.restype = None
gl.glMinSampleShading.argtypes = [c_float]
gl.glMinSampleShading.restype = None
gl.glObjectLabel.argtypes = [
c_uint,
c_uint32,
c_size_t,
POINTER(c_char),
]
gl.glObjectLabel.restype = None
gl.glObjectPtrLabel.argtypes = [c_void_p, c_size_t, POINTER(c_char)]
gl.glObjectPtrLabel.restype = None
gl.glPatchParameteri.argtypes = [c_uint, c_int32]
gl.glPatchParameteri.restype = None
gl.glPauseTransformFeedback.argtypes = None
gl.glPauseTransformFeedback.restype = None
gl.glPixelStorei.argtypes = [c_uint, c_long]
gl.glPixelStorei.restype = None
gl.glPolygonOffset.argtypes = [c_float, c_float]
gl.glPolygonOffset.restype = None
gl.glPopDebugGroup.argtypes = None
gl.glPopDebugGroup.restype = None
gl.glProgramBinary.argtypes = [c_uint32, c_uint, c_void_p, c_size_t]
gl.glProgramBinary.restype = None
gl.glProgramParameteri.argtypes = [c_uint32, c_uint, c_int32]
gl.glProgramParameteri.restype = None
gl.glProgramUniform1f.argtypes = [c_uint32, c_int32, c_float]
gl.glProgramUniform1f.restype = None
gl.glProgramUniform1fv.argtypes = [
c_uint32,
c_int32,
c_size_t,
POINTER(c_float),
]
gl.glProgramUniform1fv.restype = None
gl.glProgramUniform1i.argtypes = [c_uint32, c_int32, c_int32]
gl.glProgramUniform1i.restype = None
gl.glProgramUniform1iv.argtypes = [
c_uint32,
c_int32,
c_size_t,
POINTER(c_int32),
]
gl.glProgramUniform1iv.restype = None
gl.glProgramUniform1ui.argtypes = [c_uint32, c_int32, c_uint32]
gl.glProgramUniform1ui.restype = None
gl.glProgramUniform1uiv.argtypes = [
c_uint32,
c_int32,
c_size_t,
POINTER(c_uint32),
]
gl.glProgramUniform1uiv.restype = None
gl.glProgramUniform2f.argtypes = [c_uint32, c_int32, c_float, c_float]
gl.glProgramUniform2f.restype = None
gl.glProgramUniform2fv.argtypes = [
c_uint32,
c_int32,
c_size_t,
POINTER(c_float),
]
gl.glProgramUniform2fv.restype = None
gl.glProgramUniform2i.argtypes = [c_uint32, c_int32, c_int32, c_int32]
gl.glProgramUniform2i.restype = None
gl.glProgramUniform2iv.argtypes = [
c_uint32,
c_int32,
c_size_t,
POINTER(c_int32),
]
gl.glProgramUniform2iv.restype = None
gl.glProgramUniform2ui.argtypes = [
c_uint32,
c_int32,
c_uint32,
c_uint32,
]
gl.glProgramUniform2ui.restype = None
gl.glProgramUniform2uiv.argtypes = [
c_uint32,
c_int32,
c_size_t,
POINTER(c_uint32),
]
gl.glProgramUniform2uiv.restype = None
gl.glProgramUniform3f.argtypes = [
c_uint32,
c_int32,
c_float,
c_float,
c_float,
]
gl.glProgramUniform3f.restype = None
gl.glProgramUniform3fv.argtypes = [
c_uint32,
c_int32,
c_size_t,
POINTER(c_float),
]
gl.glProgramUniform3fv.restype = None
gl.glProgramUniform3i.argtypes = [
c_uint32,
c_int32,
c_int32,
c_int32,
c_int32,
]
gl.glProgramUniform3i.restype = None
gl.glProgramUniform3iv.argtypes = [
c_uint32,
c_int32,
c_size_t,
POINTER(c_int32),
]
gl.glProgramUniform3iv.restype = None
gl.glProgramUniform3ui.argtypes = [
c_uint32,
c_int32,
c_uint32,
c_uint32,
c_uint32,
]
gl.glProgramUniform3ui.restype = None
gl.glProgramUniform3uiv.argtypes = [
c_uint32,
c_int32,
c_size_t,
POINTER(c_uint32),
]
gl.glProgramUniform3uiv.restype = None
gl.glProgramUniform4f.argtypes = [
c_uint32,
c_int32,
c_float,
c_float,
c_float,
c_float,
]
gl.glProgramUniform4f.restype = None
gl.glProgramUniform4fv.argtypes = [
c_uint32,
c_int32,
c_size_t,
POINTER(c_float),
]
gl.glProgramUniform4fv.restype = None
gl.glProgramUniform4i.argtypes = [
c_uint32,
c_int32,
c_int32,
c_int32,
c_int32,
c_int32,
]
gl.glProgramUniform4i.restype = None
gl.glProgramUniform4iv.argtypes = [
c_uint32,
c_int32,
c_size_t,
POINTER(c_int32),
]
gl.glProgramUniform4iv.restype = None
gl.glProgramUniform4ui.argtypes = [
c_uint32,
c_int32,
c_uint32,
c_uint32,
c_uint32,
c_uint32,
]
gl.glProgramUniform4ui.restype = None
gl.glProgramUniform4uiv.argtypes = [
c_uint32,
c_int32,
c_size_t,
POINTER(c_uint32),
]
gl.glProgramUniform4uiv.restype = None
gl.glProgramUniformMatrix2fv.argtypes = [
c_uint32,
c_int32,
c_size_t,
c_ubyte,
POINTER(c_float),
]
gl.glProgramUniformMatrix2fv.restype = None
gl.glProgramUniformMatrix2x3fv.argtypes = [
c_uint32,
c_int32,
c_size_t,
c_ubyte,
POINTER(c_float),
]
gl.glProgramUniformMatrix2x3fv.restype = None
gl.glProgramUniformMatrix2x4fv.argtypes = [
c_uint32,
c_int32,
c_size_t,
c_ubyte,
POINTER(c_float),
]
gl.glProgramUniformMatrix2x4fv.restype = None
gl.glProgramUniformMatrix3fv.argtypes = [
c_uint32,
c_int32,
c_size_t,
c_ubyte,
POINTER(c_float),
]
gl.glProgramUniformMatrix3fv.restype = None
gl.glProgramUniformMatrix3x2fv.argtypes = [
c_uint32,
c_int32,
c_size_t,
c_ubyte,
POINTER(c_float),
]
gl.glProgramUniformMatrix3x2fv.restype = None
gl.glProgramUniformMatrix3x4fv.argtypes = [
c_uint32,
c_int32,
c_size_t,
c_ubyte,
POINTER(c_float),
]
gl.glProgramUniformMatrix3x4fv.restype = None
gl.glProgramUniformMatrix4fv.argtypes = [
c_uint32,
c_int32,
c_size_t,
c_ubyte,
POINTER(c_float),
]
gl.glProgramUniformMatrix4fv.restype = None
gl.glProgramUniformMatrix4x2fv.argtypes = [
c_uint32,
c_int32,
c_size_t,
c_ubyte,
POINTER(c_float),
]
gl.glProgramUniformMatrix4x2fv.restype = None
gl.glProgramUniformMatrix4x3fv.argtypes = [
c_uint32,
c_int32,
c_size_t,
c_ubyte,
POINTER(c_float),
]
gl.glProgramUniformMatrix4x3fv.restype = None
gl.glPushDebugGroup.argtypes = [
c_uint,
c_uint32,
c_size_t,
POINTER(c_char),
]
gl.glPushDebugGroup.restype = None
gl.glReadBuffer.argtypes = [c_uint]
gl.glReadBuffer.restype = None
gl.glReadPixels.argtypes = [
c_int,
c_int,
c_size_t,
c_size_t,
c_uint,
c_uint,
c_void_p,
]
gl.glReadPixels.restype = None
gl.glReleaseShaderCompiler.argtypes = None
gl.glReleaseShaderCompiler.restype = None
gl.glRenderbufferStorage.argtypes = [
c_uint,
c_uint,
c_size_t,
c_size_t,
]
gl.glRenderbufferStorage.restype = None
gl.glRenderbufferStorageMultisample.argtypes = [
c_uint,
c_size_t,
c_uint,
c_size_t,
c_size_t,
]
gl.glRenderbufferStorageMultisample.restype = None
gl.glResumeTransformFeedback.argtypes = None
gl.glResumeTransformFeedback.restype = None
gl.glSampleCoverage.argtypes = [c_float, c_ubyte]
gl.glSampleCoverage.restype = None
gl.glSampleMaski.argtypes = [c_uint32, c_uint]
gl.glSampleMaski.restype = None
gl.glSamplerParameterIiv.argtypes = [
c_uint32,
c_uint,
POINTER(c_int32),
]
gl.glSamplerParameterIiv.restype = None
gl.glSamplerParameterIuiv.argtypes = [
c_uint32,
c_uint,
POINTER(c_uint32),
]
gl.glSamplerParameterIuiv.restype = None
gl.glSamplerParameterf.argtypes = [c_uint32, c_uint, c_float]
gl.glSamplerParameterf.restype = None
gl.glSamplerParameterfv.argtypes = [c_uint32, c_uint, POINTER(c_float)]
gl.glSamplerParameterfv.restype = None
gl.glSamplerParameteri.argtypes = [c_uint32, c_uint, c_int32]
gl.glSamplerParameteri.restype = None
gl.glSamplerParameteriv.argtypes = [c_uint32, c_uint, POINTER(c_int32)]
gl.glSamplerParameteriv.restype = None
gl.glScissor.argtypes = [c_int, c_int, c_size_t, c_size_t]
gl.glScissor.restype = None
gl.glShaderBinary.argtypes = [
c_size_t,
POINTER(c_uint32),
c_uint,
c_void_p,
c_size_t,
]
gl.glShaderBinary.restype = None
gl.glShaderSource.argtypes = [
c_uint32,
c_size_t,
POINTER(c_char_p),
POINTER(c_int32),
]
gl.glShaderSource.restype = None
gl.glStencilFunc.argtypes = [c_uint, c_int, c_uint]
gl.glStencilFunc.restype = None
gl.glStencilFuncSeparate.argtypes = [c_uint, c_uint, c_int, c_uint]
gl.glStencilFuncSeparate.restype = None
gl.glStencilMask.argtypes = [c_uint]
gl.glStencilMask.restype = None
gl.glStencilMaskSeparate.argtypes = [c_uint, c_uint]
gl.glStencilMaskSeparate.restype = None
gl.glStencilOp.argtypes = [c_uint, c_uint, c_uint]
gl.glStencilOp.restype = None
gl.glStencilOpSeparate.argtypes = [c_uint, c_uint, c_uint, c_uint]
gl.glStencilOpSeparate.restype = None
gl.glTexBuffer.argtypes = [c_uint, c_uint, c_uint32]
gl.glTexBuffer.restype = None
gl.glTexBufferRange.argtypes = [
c_uint,
c_uint,
c_uint32,
c_size_t,
c_ssize_t,
]
gl.glTexBufferRange.restype = None
gl.glTexImage2D.argtypes = [
c_uint,
c_long,
c_int,
c_size_t,
c_size_t,
c_long,
c_uint,
c_uint,
c_void_p,
]
gl.glTexImage2D.restype = None
gl.glTexParameterIiv.argtypes = [c_uint, c_uint, POINTER(c_int32)]
gl.glTexParameterIiv.restype = None
gl.glTexParameterIuiv.argtypes = [c_uint, c_uint, POINTER(c_uint32)]
gl.glTexParameterIuiv.restype = None
gl.glTexParameterf.argtypes = [c_uint, c_uint, c_float]
gl.glTexParameterf.restype = None
gl.glTexParameterfv.argtypes = [c_uint, c_uint, POINTER(c_float)]
gl.glTexParameterfv.restype = None
gl.glTexParameteri.argtypes = [c_uint, c_uint, c_long]
gl.glTexParameteri.restype = None
gl.glTexParameteriv.argtypes = [c_uint, c_uint, POINTER(c_long)]
gl.glTexParameteriv.restype = None
gl.glTexStorage2D.argtypes = [
c_uint,
c_size_t,
c_uint,
c_size_t,
c_size_t,
]
gl.glTexStorage2D.restype = None
gl.glTexStorage2DMultisample.argtypes = [
c_uint,
c_size_t,
c_uint,
c_size_t,
c_size_t,
c_ubyte,
]
gl.glTexStorage2DMultisample.restype = None
gl.glTexStorage3D.argtypes = [
c_uint,
c_size_t,
c_uint,
c_size_t,
c_size_t,
c_size_t,
]
gl.glTexStorage3D.restype = None
gl.glTexStorage3DMultisample.argtypes = [
c_uint,
c_size_t,
c_uint,
c_size_t,
c_size_t,
c_size_t,
c_ubyte,
]
gl.glTexStorage3DMultisample.restype = None
gl.glTexSubImage2D.argtypes = [
c_uint,
c_long,
c_long,
c_long,
c_size_t,
c_size_t,
c_uint,
c_uint,
c_void_p,
]
gl.glTexSubImage2D.restype = None
gl.glTexSubImage3D.argtypes = [
c_uint,
c_long,
c_long,
c_long,
c_long,
c_size_t,
c_size_t,
c_size_t,
c_uint,
c_uint,
c_void_p,
]
gl.glTexSubImage3D.restype = None
gl.glTransformFeedbackVaryings.argtypes = [
c_uint32,
c_size_t,
POINTER(c_char_p),
c_uint,
]
gl.glTransformFeedbackVaryings.restype = None
gl.glUniform1f.argtypes = [c_int32, c_float]
gl.glUniform1f.restype = None
gl.glUniform1fv.argtypes = [c_int32, c_size_t, POINTER(c_float)]
gl.glUniform1fv.restype = None
gl.glUniform1i.argtypes = [c_int32, c_int32]
gl.glUniform1i.restype = None
gl.glUniform1iv.argtypes = [c_int32, c_size_t, POINTER(c_int32)]
gl.glUniform1iv.restype = None
gl.glUniform1ui.argtypes = [c_int32, c_uint32]
gl.glUniform1ui.restype = None
gl.glUniform1uiv.argtypes = [c_int32, c_size_t, POINTER(c_uint32)]
gl.glUniform1uiv.restype = None
gl.glUniform2f.argtypes = [c_int32, c_float, c_float]
gl.glUniform2f.restype = None
gl.glUniform2fv.argtypes = [c_int32, c_size_t, POINTER(c_float)]
gl.glUniform2fv.restype = None
gl.glUniform2i.argtypes = [c_int32, c_int32, c_int32]
gl.glUniform2i.restype = None
gl.glUniform2iv.argtypes = [c_int32, c_size_t, POINTER(c_int32)]
gl.glUniform2iv.restype = None
gl.glUniform2ui.argtypes = [c_int32, c_uint32, c_uint32]
gl.glUniform2ui.restype = None
gl.glUniform2uiv.argtypes = [c_int32, c_size_t, POINTER(c_uint32)]
gl.glUniform2uiv.restype = None
gl.glUniform3f.argtypes = [c_int32, c_float, c_float, c_float]
gl.glUniform3f.restype = None
gl.glUniform3fv.argtypes = [c_int32, c_size_t, POINTER(c_float)]
gl.glUniform3fv.restype = None
gl.glUniform3i.argtypes = [c_int32, c_int32, c_int32, c_int32]
gl.glUniform3i.restype = None
gl.glUniform3iv.argtypes = [c_int32, c_size_t, POINTER(c_int32)]
gl.glUniform3iv.restype = None
gl.glUniform3ui.argtypes = [c_int32, c_uint32, c_uint32, c_uint32]
gl.glUniform3ui.restype = None
gl.glUniform3uiv.argtypes = [c_int32, c_size_t, POINTER(c_uint32)]
gl.glUniform3uiv.restype = None
gl.glUniform4f.argtypes = [c_int32, c_float, c_float, c_float, c_float]
gl.glUniform4f.restype = None
gl.glUniform4fv.argtypes = [c_int32, c_size_t, POINTER(c_float)]
gl.glUniform4fv.restype = None
gl.glUniform4i.argtypes = [c_int32, c_int32, c_int32, c_int32, c_int32]
gl.glUniform4i.restype = None
gl.glUniform4iv.argtypes = [c_int32, c_size_t, POINTER(c_int32)]
gl.glUniform4iv.restype = None
gl.glUniform4ui.argtypes = [
c_int32,
c_uint32,
c_uint32,
c_uint32,
c_uint32,
]
gl.glUniform4ui.restype = None
gl.glUniform4uiv.argtypes = [c_int32, c_size_t, POINTER(c_uint32)]
gl.glUniform4uiv.restype = None
gl.glUniformBlockBinding.argtypes = [c_uint32, c_uint32, c_uint32]
gl.glUniformBlockBinding.restype = None
gl.glUniformMatrix2fv.argtypes = [
c_int32,
c_size_t,
c_ubyte,
POINTER(c_float),
]
gl.glUniformMatrix2fv.restype = None
gl.glUniformMatrix2x3fv.argtypes = [
c_int32,
c_size_t,
c_ubyte,
POINTER(c_float),
]
gl.glUniformMatrix2x3fv.restype = None
gl.glUniformMatrix2x4fv.argtypes = [
c_int32,
c_size_t,
c_ubyte,
POINTER(c_float),
]
gl.glUniformMatrix2x4fv.restype = None
gl.glUniformMatrix3fv.argtypes = [
c_int32,
c_size_t,
c_ubyte,
POINTER(c_float),
]
gl.glUniformMatrix3fv.restype = None
gl.glUniformMatrix3x2fv.argtypes = [
c_int32,
c_size_t,
c_ubyte,
POINTER(c_float),
]
gl.glUniformMatrix3x2fv.restype = None
gl.glUniformMatrix3x4fv.argtypes = [
c_int32,
c_size_t,
c_ubyte,
POINTER(c_float),
]
gl.glUniformMatrix3x4fv.restype = None
gl.glUniformMatrix4fv.argtypes = [
c_int32,
c_size_t,
c_ubyte,
POINTER(c_float),
]
gl.glUniformMatrix4fv.restype = None
gl.glUniformMatrix4x2fv.argtypes = [
c_int32,
c_size_t,
c_ubyte,
POINTER(c_float),
]
gl.glUniformMatrix4x2fv.restype = None
gl.glUniformMatrix4x3fv.argtypes = [
c_int32,
c_size_t,
c_ubyte,
POINTER(c_float),
]
gl.glUniformMatrix4x3fv.restype = None
gl.glUnmapBuffer.argtypes = [c_uint]
gl.glUnmapBuffer.restype = c_ubyte
gl.glUseProgram.argtypes = [c_uint32]
gl.glUseProgram.restype = None
gl.glUseProgramStages.argtypes = [c_uint32, c_uint, c_uint32]
gl.glUseProgramStages.restype = None
gl.glValidateProgram.argtypes = [c_uint32]
gl.glValidateProgram.restype = None
gl.glValidateProgramPipeline.argtypes = [c_uint32]
gl.glValidateProgramPipeline.restype = None
gl.glVertexAttribBinding.argtypes = [c_uint32, c_uint32]
gl.glVertexAttribBinding.restype = None
gl.glVertexAttribDivisor.argtypes = [c_uint32, c_uint32]
gl.glVertexAttribDivisor.restype = None
gl.glVertexAttribFormat.argtypes = [
c_uint32,
c_int32,
c_uint,
c_ubyte,
c_uint32,
]
gl.glVertexAttribFormat.restype = None
gl.glVertexAttribIFormat.argtypes = [
c_uint32,
c_int32,
c_uint,
c_uint32,
]
gl.glVertexAttribIFormat.restype = None
gl.glVertexAttribIPointer.argtypes = [
c_uint32,
c_int32,
c_uint,
c_size_t,
c_void_p,
]
gl.glVertexAttribIPointer.restype = None
gl.glVertexAttribPointer.argtypes = [
c_uint32,
c_int32,
c_uint,
c_ubyte,
c_size_t,
c_void_p,
]
gl.glVertexAttribPointer.restype = None
gl.glVertexBindingDivisor.argtypes = [c_uint32, c_uint32]
gl.glVertexBindingDivisor.restype = None
gl.glViewport.argtypes = [c_int, c_int, c_size_t, c_size_t]
gl.glViewport.restype = None
'''
class PageAnalyzer(object):
"""Analyzer for kernel page"""
# page flags from kernel/include/uapi/linux/kernel-page-flags.h #
flagList = [
"KPF_LOCKED", # 0
"KPF_ERROR", # 1
"KPF_REFERENCED", # 2
"KPF_UPTODATE", # 3
"KPF_DIRTY", # 4
"KPF_LRU", # 5
"KPF_ACTIVE", # 6
"KPF_SLAB", # 7
"KPF_WRITEBACK", # 8
"KPF_RECLAIM", # 9
"KPF_BUDDY", # 10
"KPF_MMAP", # 11
"KPF_ANON", # 12
"KPF_SWAPCACHE", # 13
"KPF_SWAPBACKED", # 14
"KPF_COMPOUND_HEAD", # 15
"KPF_COMPOUND_TAIL", # 16
"KPF_HUGE", # 17
"KPF_UNEVICTABLE", # 18
"KPF_HWPOISON", # 19
"KPF_NOPAGE", # 20
"KPF_KSM", # 21
"KPF_THP", # 22
"KPF_BALLOON", # 23
"KPF_ZERO_PAGE", # 24
"KPF_IDLE", # 25
]
@staticmethod
def getPageInfo(
pid,
vaddr,
markIdle=False,
checkIdle=False,
retList=False,
verb=True,
progress=False,
):
try:
if not pid:
raise Exception("no pid")
elif type(pid) is not list:
raise Exception("wrong pid")
pids = []
for item in pid:
ret = SysMgr.getTids(item, isThread=False)
if ret:
pids += ret
if not pids:
raise Exception("no task")
except SystemExit:
sys.exit(0)
except:
if pid:
targetStr = " for '%s'" % ", ".join(pid)
else:
targetStr = ""
SysMgr.printErr("failed to find task%s" % targetStr, reason=True)
sys.exit(-1)
# check root permission #
SysMgr.checkRootPerm()
# get target addresses #
if vaddr:
vaddrOrig = UtilMgr.cleanItem(vaddr.split(","), False)
else:
vaddrOrig = None
# update verb #
if verb and not SysMgr.printEnable:
verb = False
# set print function #
if verb:
_printPipe = SysMgr.printPipe
else:
_printPipe = lambda _: True
# check idle page marking #
if "MARKIDLE" in SysMgr.environList:
markIdle = True
if not SysMgr.checkIdlePageCond():
sys.exit(-1)
# check idle page checking #
if "CHECKIDLE" in SysMgr.environList:
checkIdle = True
# check bitmap saving #
if "SAVEBITMAP" in SysMgr.environList:
saveBitmapFlag = True
else:
saveBitmapFlag = False
# define shortcut variables #
convNum = UtilMgr.convNum
convSize = UtilMgr.convSize2Unit
errMsg = (
"failed to recognize addresses, "
"input the address such as 102400 or 0x1234a-0x123ff"
)
idlePageList = {}
for pidx, pid in enumerate(sorted(pids)):
# read whole bitmap for idle pages #
if checkIdle:
bitmap = SysMgr.getIdleMap()
else:
bitmap = None
# get process name #
comm = SysMgr.getComm(pid)
vaddrs = vaddrOrig
if not vaddrs:
PageAnalyzer.printMemoryArea(
pid, comm=comm, showall=SysMgr.showAll, lastLine=True
)
continue
if retList:
idlePageList.setdefault(pid, [])
# get target address ranges #
targetList = []
for vaddr in vaddrs:
if not vaddr:
continue
# get address range #
if vaddr in ("heap", "stack"):
vaddr = "[%s]" % vaddr
# get addresses by name #
vrange = FileAnalyzer.getMapAddr(pid, vaddr)
if not vrange:
SysMgr.printErr(
"failed to find memory address for '%s'" % vaddr
)
continue
targetList.append(vrange)
else:
# get addresses by file #
vranges = FileAnalyzer.getMapAddr(pid, vaddr, retList=True)
if vranges:
targetList += vranges
else:
vrange = UtilMgr.cleanItem(vaddr.split("-"), False)
targetList.append(vrange)
procPresent = 0
procSwapped = 0
procSoftdirty = 0
procExmapped = 0
procFile = 0
procRef = 0
procIdle = 0
procTotalFlags = 0
pageTable = []
# print page info in target address ranges #
for vcnt, vrange in enumerate(targetList):
# print progress #
if progress:
UtilMgr.printProgress(vcnt, len(targetList))
rangeCnt = len(vrange)
# check input count #
if rangeCnt > 2:
SysMgr.printErr(errMsg, True)
sys.exit(-1)
# check input format #
try:
addrs = long(vrange[0], base=16)
addre = addrs
except SystemExit:
sys.exit(0)
except:
SysMgr.printErr(errMsg, True)
sys.exit(-1)
try:
if rangeCnt == 2:
addre = long(vrange[1], base=16)
offset = 0
else:
offset = SysMgr.PAGESIZE
# check range #
if addrs > addre:
if verb:
# print memory area #
PageAnalyzer.printMemoryArea(
pid, comm=comm, showall=True, lastLine=True
)
# print error message #
SysMgr.printErr(
(
"failed to recognize addresses, "
"the first address (%s) is bigger than "
"the second address (%s)"
)
% (hex(addrs), hex(addre))
)
sys.exit(-1)
except SystemExit:
sys.exit(0)
except:
SysMgr.printErr(errMsg, True)
sys.exit(-1)
_printPipe(
"\n[Mem Info] [Proc: %s(%s)] [AREA: %s] [HELP: %s]"
% (comm, pid, vaddr, "kernel/Documentation/vm/pagemap.txt")
)
# print memory area info #
if verb:
PageAnalyzer.printMemoryArea(
pid, addrs, addre, lastLine=True
)
# print menu #
_printPipe(
(
"{0:^19}|{1:^16}|{2:>5}|{3:>5}|{4:>5}|{5:>5}|"
"{6:>5}|{7:>5}|{8:>5}| {9} ({10})\n{11}"
).format(
"VADDR",
"PFN",
"PRES",
"SWAP",
"FILE",
"SHR",
"SDRT",
"EXMAP",
"IDLE",
"ATTRIBUTES",
"BITS",
oneLine,
)
)
# init total variables #
totalPresent = 0
totalSwapped = 0
totalSoftdirty = 0
totalExmapped = 0
totalFile = 0
totalRef = 0
totalIdle = 0
totalFlags = 0
# read pagemap #
addreNew = addre + offset
length = addreNew - addrs
pagemap = PageAnalyzer.getPagemap(pid, addrs, length)
# create a new pagetable for this area #
if retList or (saveBitmapFlag and checkIdle):
pageSubTable = [1] * long(length / SysMgr.PAGESIZE)
idx = 0
for addr in xrange(addrs, addreNew, SysMgr.PAGESIZE):
# get page frame info #
try:
entry = struct.unpack("Q", pagemap[idx : idx + 8])[0]
except SystemExit:
sys.exit(0)
except:
entry = 0
finally:
idx += 8
# get page frame number #
pfn = PageAnalyzer.getPfn(entry)
# no page #
isIdle = "-"
# mark idle pages #
if markIdle:
if SysMgr.handleIdlePage(pfn, write=True):
isIdle = True
totalIdle += 1
procIdle += 1
# check idle pages #
elif checkIdle:
isIdle = SysMgr.handleIdlePage(
pfn, write=False, bitmap=bitmap
)
if isIdle is None:
isIdle = "-"
elif isIdle:
totalIdle += 1
procIdle += 1
# change a bit in a pagetable #
if retList or saveBitmapFlag:
try:
pageSubTable[long(idx / 8) - 1] = 0
except:
SysMgr.printWarn(
"failed to save an idle page status",
always=True,
reason=True,
)
# check skip condition #
if not verb:
continue
isPresent = PageAnalyzer.isPresent(entry)
if isPresent:
totalPresent += 1
procPresent += 1
isSwapped = PageAnalyzer.isSwapped(entry)
if isSwapped:
totalSwapped += 1
procSwapped += 1
isSoftdirty = PageAnalyzer.isSoftdirty(entry)
if isSoftdirty:
totalSoftdirty += 1
procSoftdirty += 1
isExmapped = PageAnalyzer.isExmapped(entry)
if isExmapped:
totalExmapped += 1
procExmapped += 1
isFile = PageAnalyzer.isFilePage(entry)
if isFile:
totalFile += 1
procFile += 1
refCnt = PageAnalyzer.getPageCount(pfn)
if refCnt > 1:
refCnt = 1
totalRef += 1
procRef += 1
else:
refCnt = 0
kflags = PageAnalyzer.getPageFlags(pfn)
totalFlags |= kflags
if kflags:
bflags = hex(kflags).rstrip("L")
sflags = PageAnalyzer.getFlagTypes(bflags)
bflags = "(%s)" % bflags
else:
sflags = bflags = ""
if SysMgr.showAll:
SysMgr.addPrint(
(
"{0:>18} |{1:>15} |{2:>5}|{3:>5}|{4:>5}|"
"{5:>5}|{6:>5}|{7:>5}|{8:>5}| {9} {10}\n"
).format(
hex(addr).rstrip("L"),
hex(pfn).rstrip("L") if pfn else "",
isPresent,
isSwapped,
isFile,
convSize(refCnt, isInt=True),
isSoftdirty,
isExmapped,
isIdle,
sflags,
bflags,
),
force=True,
isList=True,
)
procTotalFlags |= totalFlags
totalFlagsStr = hex(totalFlags).rstrip("L")
# print total stats #
_printPipe(
(
"{0:>18} |{1:>15} |{2:>5}|{3:>5}|{4:>5}|"
"{5:>5}|{6:>5}|{7:>5}|{8:>5}| {9} ({10})\n{11:1}"
).format(
"[TOTAL]",
"",
convSize(totalPresent, isInt=True),
convSize(totalSwapped, isInt=True),
convSize(totalFile, isInt=True),
convSize(totalRef, isInt=True),
convSize(totalSoftdirty, isInt=True),
convSize(totalExmapped, isInt=True),
convSize(totalIdle, isInt=True),
PageAnalyzer.getFlagTypes(totalFlagsStr),
totalFlagsStr,
oneLine,
)
)
# print all items #
if verb:
SysMgr.doPrint(newline=False, clear=True, isList=True)
if SysMgr.showAll:
_printPipe("%s\n" % oneLine)
else:
SysMgr.clearPrint()
# add a new area to list #
if retList:
idlePageList[pid].append([addrs, addreNew, pageSubTable])
# merge pagetables #
if saveBitmapFlag and checkIdle:
pageTable += pageSubTable
if progress:
UtilMgr.deleteProgress()
# print process memory info #
_printPipe(
"\n[Mem Info] [Proc: %s(%s)] [Area: %s)\n%s"
% (SysMgr.getComm(pid), pid, convNum(len(targetList)), twoLine)
)
_printPipe(
(
"{0:^10}|{1:^8}|{2:^8}|{3:^8}|{4:^8}|"
"{5:^8}|{6:^8}|{7:^8}| {8} ({9})\n{10}"
).format(
"[TOTAL]",
"PRESENT",
"SWAP",
"FILE",
"SHR",
"SDRT",
"EXMAP",
"IDLE",
"ATTRIBUTES",
"BITS",
oneLine,
)
)
procTotalFlagsStr = hex(procTotalFlags).rstrip("L")
# print total page stats #
_printPipe(
(
"{0:^9} |{1:>7} |{2:>7} |{3:>7} |"
"{4:>7} |{5:>7} |{6:>7} |{7:>7} | {8}"
).format(
"PAGE",
convNum(procPresent),
convNum(procSwapped),
convNum(procFile),
convSize(procRef, isInt=True),
convNum(procSoftdirty),
convNum(procExmapped),
convNum(procIdle) if checkIdle or markIdle else "-",
PageAnalyzer.getFlagTypes(procTotalFlagsStr),
)
)
# print total size stats #
_printPipe(
(
"{0:^9} |{1:>7} |{2:>7} |{3:>7} |"
"{4:>7} |{5:>7} |{6:>7} |{7:>7} | {8}\n{9}"
).format(
"SIZE",
convSize(procPresent << 12),
convSize(procSwapped << 12),
convSize(procFile << 12),
convSize(procRef << 12, isInt=True),
convSize(procSoftdirty << 12),
convSize(procExmapped << 12),
convSize(procIdle << 12) if checkIdle or markIdle else "-",
procTotalFlagsStr,
oneLine,
)
)
# save idle bitmap to the file #
if saveBitmapFlag and checkIdle:
if SysMgr.printFd:
filename = SysMgr.printFd.name
name, ext = os.path.splitext(filename)
filename = "%s_idlemap%s%s" % (name, pid, ext)
else:
filename = "idlemap.out"
# backup #
SysMgr.backupFile(filename)
# save bitmap to the file #
try:
with open(filename, "wb") as fd:
btable = bytes(pageTable)
fd.write(btable)
os.chmod(filename, 0o777)
except:
SysMgr.printOpenErr(filename)
continue
# get output size #
fsize = UtilMgr.getFileSizeStr(filename)
SysMgr.printStat(
"saved the bitmap data to '%s'%s successfully"
% (filename, fsize)
)
# print split line between proceses #
if pidx < len(pids) - 1:
_printPipe("\n\n" + splitLine + "\n\n")
return idlePageList
@staticmethod
def printMemoryArea(
pid, start=-1, end=-1, comm=None, lastLine=False, showall=True
):
count = 0
switch = False
fpath = "%s/%s/maps" % (SysMgr.procPath, pid)
if start == end == -1 and not showall:
summaryFlag = True
else:
summaryFlag = False
# read all map info #
try:
# summary #
if summaryFlag:
buf = FileAnalyzer.getProcMapInfo(pid, saveAll=True)
else:
with open(fpath, "r") as fd:
buf = fd.readlines()
except SystemExit:
sys.exit(0)
except:
SysMgr.printOpenErr(fpath)
sys.exit(-1)
convSize = UtilMgr.convSize2Unit
if start == end == -1:
if not comm:
comm = SysMgr.getComm(pid)
# get mem stat #
mlist = SysMgr.getMemStat(pid)
mstat = SysMgr.convMemStat(mlist)
vss = convSize(mstat["vss"])
rss = convSize(mstat["rss"])
SysMgr.printPipe(
"\n[Mem Info] [Proc: %s(%s)] [VSS: %s] [RSS: %s]"
% (comm, pid, vss, rss)
)
startHex = hex(start)
endHex = hex(end)
allHex = hex(-1)
# print menu #
menuStr = ""
menuBuf = menuList = [
"AREA",
"PERM",
"%8s" % "OFFSET",
"%6s" % "DEV",
"%12s" % "INODE",
"%5s" % "SIZE",
]
for idx, value in enumerate(menuBuf):
if idx < 6:
if idx == 0:
text = "{0:^38}".format(menuList[idx])
else:
text = menuList[idx]
else:
break
value = " " * (len(value) - len(text) + 1)
menuStr = "%s%s%s" % (menuStr, text, value)
menuStr += "TARGET"
SysMgr.printPipe("%s\n%s\n%s" % (twoLine, menuStr, oneLine))
# print summarized map info #
if summaryFlag:
for fname, info in sorted(
buf.items(), key=lambda e: e[1]["vstart"]
):
# skip non-contiguous segments #
if SysMgr.magicStr in fname:
continue
# convert path from overlayfs mount point #
overlayInfo = SysMgr.getOverlayfsInfo(pid)
if overlayInfo:
fname = UtilMgr.convOverlayPath(fname, overlayInfo)
try:
soffset = hex(info["vstart"]).rstrip("L")
eoffset = hex(info["vend"]).rstrip("L")
size = convSize(
long(eoffset, 16) - long(soffset, 16), True
)
if not fname.startswith("/"):
fname = "[%s]" % fname
SysMgr.printPipe(
"%18s %18s %4s %8s %6s %12s %5s %s"
% (
soffset,
eoffset,
info["perm"],
info["offset"],
info["devid"],
info["inode"],
size,
fname,
)
)
count += 1
except SystemExit:
sys.exit(0)
except:
pass
if count == 0:
SysMgr.printPipe("no involved memory area")
if lastLine:
SysMgr.printPipe(oneLine)
return
# print all map info #
for line in buf:
tmplist = line.split()
soffset, eoffset = tmplist[0].split("-")
soffset = long(soffset, base=16)
eoffset = long(eoffset, base=16)
if startHex == endHex == allHex:
switch = False
elif "-" in line:
if soffset <= start < eoffset:
switch = True
elif not switch:
continue
elif end < eoffset:
break
try:
target = line[:-1].split()
target[4] = "%12s" % target[4]
soffsetHex = hex(soffset)
eoffsetHex = hex(eoffset)
if not soffsetHex.startswith("0x"):
soffsetHex = "0x%s" % soffsetHex
if not eoffsetHex.startswith("0x"):
eoffsetHex = "0x%s" % eoffsetHex
size = convSize(eoffset - soffset, True)
# convert path from overlayfs mount point #
fname = target[5] if len(target) > 5 else " "
overlayInfo = SysMgr.getOverlayfsInfo(pid)
if overlayInfo:
fname = UtilMgr.convOverlayPath(fname, overlayInfo)
SysMgr.printPipe(
"%18s %18s %4s %8s %6s %12s %5s %s"
% (
soffsetHex,
eoffsetHex,
target[1],
target[2],
target[3],
target[4],
size,
fname,
)
)
except SystemExit:
sys.exit(0)
except:
pass
count += 1
if switch and end <= eoffset:
break
if count == 0:
SysMgr.printPipe("no involved memory area")
if lastLine:
SysMgr.printPipe(oneLine)
@staticmethod
def getFlagTypes(flags):
sflags = ""
for idx, val in enumerate(PageAnalyzer.flagList):
if (long(flags, 16) & (1 << long(idx))) != 0:
sflags += val[4:] + "|"
return sflags[:-1]
@staticmethod
def readEntry(path, offset, size=8):
try:
f = SysMgr.getFd(path)
f.seek(offset, 0)
data = f.read(size)
if data:
return struct.unpack("Q" if size == 8 else "I", data)[0]
else:
return 0
except SystemExit:
sys.exit(0)
except:
SysMgr.printErr(
"failed to read %s byte from %s of %s" % (size, offset, path),
reason=True,
)
sys.exit(-1)
@staticmethod
def getPagemapPath(pid):
path = "{0}/{1}/pagemap".format(SysMgr.procPath, pid)
if not os.path.isfile(path):
SysMgr.printErr("failed to find the process with PID %s" % pid)
sys.exit(-1)
return path
@staticmethod
def getPagemap(pid, addr, size):
path = PageAnalyzer.getPagemapPath(pid)
offset = long(addr / SysMgr.PAGESIZE) * 8
size = long(size / SysMgr.PAGESIZE) * 8
try:
f = SysMgr.getFd(path)
f.seek(offset, 0)
return f.read(size)
except SystemExit:
sys.exit(0)
except:
SysMgr.printErr(
"failed to read %s byte from %s of %s" % (size, offset, path),
reason=True,
)
sys.exit(-1)
@staticmethod
def getPagemapEntry(pid, addr):
path = PageAnalyzer.getPagemapPath(pid)
offset = long(addr / SysMgr.PAGESIZE) * 8
return PageAnalyzer.readEntry(path, offset)
@staticmethod
def getPfn(entry):
return entry & 0x7FFFFFFFFFFFFF
@staticmethod
def isPresent(entry):
return (entry & (1 << 63)) != 0
@staticmethod
def isSoftdirty(entry):
return (entry & (1 << 55)) != 0
@staticmethod
def isExmapped(entry):
return (entry & (1 << 56)) != 0
@staticmethod
def isSwapped(entry):
return (entry & (1 << 62)) != 0
@staticmethod
def isFilePage(entry):
return (entry & (1 << 61)) != 0
@staticmethod
def getPageCount(pfn):
path = SysMgr.procPath + "/kpagecount"
return PageAnalyzer.readEntry(path, pfn * 8)
@staticmethod
def getPageFlags(pfn):
path = SysMgr.procPath + "/kpageflags"
return PageAnalyzer.readEntry(path, pfn * 8)
class FunctionAnalyzer(object):
"""Analyzer for function profiling"""
symStackIdxTable = [
"CPU_TICK",
"STACK",
"PAGE_ALLOC",
"PAGE_FREE",
"BLK_READ",
"ARGUMENT",
"HEAP_EXPAND",
"HEAP_REDUCE",
"IGNORE",
"BLK_WRITE",
"LOCK_TRY",
"UNLOCK",
"SYSCALL",
"CUSTOM",
]
def __init__(self, logFile):
self.cpuEnabled = False
self.memEnabled = False
self.heapEnabled = False
self.breadEnabled = False
self.bwriteEnabled = False
self.sigEnabled = False
self.lockEnabled = False
self.sysEnabled = False
self.sort = "sym"
self.connObj = None
self.finishTime = "0"
self.lastTime = "0"
self.totalTime = 0
self.totalTick = 0
self.prevTime = "0"
self.prevTid = "0"
self.lastCore = None
self.coreCtx = {}
self.nowCtx = None
self.nowEvent = None
self.savedEvent = None
self.nestedEvent = None
self.nowCnt = 0
self.savedCnt = 0
self.nestedCnt = 0
self.nowArg = 0
self.savedArg = 0
self.nestedArg = 0
self.duplicatedPos = 0
self.periodicEventCnt = 0
self.periodicContEventCnt = 0
self.periodicEventInterval = 0
self.heapExpEventCnt = 0
self.heapExpSize = 0
self.heapRedEventCnt = 0
self.heapRedSize = 0
self.pageAllocEventCnt = 0
self.pageAllocCnt = 0
self.pageFreeEventCnt = 0
self.pageFreeCnt = 0
self.pageUnknownFreeCnt = 0
self.pageUsageCnt = 0
self.blockRdEventCnt = 0
self.blockRdUsageCnt = 0
self.blockWrEventCnt = 0
self.blockWrUsageCnt = 0
self.lockTryEventCnt = 0
self.unlockEventCnt = 0
self.customCnt = 0
self.customTotal = 0
self.syscallCnt = 0
self.customEventTable = {}
self.ignoreTable = {}
self.mapData = []
self.pageTable = {}
self.oldPageTable = {}
self.heapTable = {}
self.oldHeapTable = {}
self.posData = {}
self.userSymData = {}
self.userFileData = {}
self.kerSymData = {}
self.threadData = {}
self.syscallTable = {}
self.customCallData = []
self.lockCallData = []
self.sysCallData = []
self.userCallData = []
self.kernelCallData = []
"""
userCallData = kernelCallData = \
[pos, stack, event, eventCnt, eventArg]
"""
self.init_threadData = {
"comm": "?",
"tgid": "-" * 5,
"target": False,
"cpuTick": 0,
"die": False,
"new": False,
"nrPages": 0,
"userPages": 0,
"cachePages": 0,
"kernelPages": 0,
"heapSize": 0,
"eventCnt": 0,
"nrWrBlocks": 0,
"customCnt": 0,
"nrUnknownFreePages": 0,
"nrKnownFreePages": 0,
"nrRdBlocks": 0,
"nrLockTry": 0,
"nrUnlock": 0,
"customTotal": 0,
"nrSyscall": 0,
"syscallTable": None,
"lastNrSyscall": -1,
}
self.init_posData = {
"symbol": "",
"binary": "",
"origBin": "",
"offset": hex(0),
"posCnt": 0,
"userPageCnt": 0,
"cachePageCnt": 0,
"kernelPageCnt": 0,
"totalCnt": 0,
"blockRdCnt": 0,
"blockWrCnt": 0,
"pageCnt": 0,
"heapSize": 0,
"unknownPageFreeCnt": 0,
"src": "",
"customCnt": 0,
"customTotal": 0,
"lockTryCnt": 0,
"unlockCnt": 0,
"syscallCnt": 0,
}
self.init_symData = {
"pos": "",
"origBin": "",
"tickCnt": 0,
"blockRdCnt": 0,
"pageCnt": 0,
"unknownPageFreeCnt": 0,
"stack": None,
"symStack": None,
"userPageCnt": 0,
"cachePageCnt": 0,
"kernelPageCnt": 0,
"heapSize": 0,
"blockWrCnt": 0,
"customCnt": 0,
"customTotal": 0,
"pagePair": None,
"pagePairCnt": 0,
"pagePairTotal": 0.0,
"pagePairMin": 0.0,
"pagePairMax": 0.0,
"pagePairAvr": 0.0,
"pageRemainMin": 0.0,
"pageRemainMax": 0.0,
"pageRemainAvr": 0.0,
"pageRemainTotal": 0.0,
"lockTryCnt": 0,
"unlockCnt": 0,
"syscallCnt": 0,
"totalTickCnt": 0,
}
self.init_ctxData = {
"nestedEvent": None,
"savedEvent": None,
"nowEvent": None,
"nested": 0,
"recStat": False,
"nestedCnt": 0,
"savedCnt": 0,
"nowCnt": 0,
"nestedArg": None,
"savedArg": None,
"prevMode": None,
"curMode": None,
"userLastPos": "",
"userStack": None,
"kerLastPos": "",
"kerStack": None,
"prevKerLastPos": "",
"prevKerStack": None,
"nowArg": None,
"prevTid": None,
"prevTime": None,
}
self.init_pageLinkData = {
"sym": "0",
"subStackAddr": 0,
"ksym": "0",
"ksubStackAddr": 0,
"type": "0",
"time": "0",
}
self.init_heapSegData = {
"tid": "0",
"size": 0,
"sym": "0",
"subStackAddr": 0,
"ksym": "0",
"ksubStackAddr": 0,
"time": 0.0,
"core": "0",
}
self.init_pageData = {
"tid": "0",
"page": "0",
"flags": "0",
"type": "0",
"time": "0",
}
self.init_glueData = {
"count": 0,
"size": 0,
"timeList": None,
"valueList": None,
}
self.init_subStackPageInfo = [0, 0, 0]
# subStackPageInfo = [userPageCnt, cachePageCnt, kernelPageCnt]
# read trace data #
lines = TaskAnalyzer.readTraceData(logFile)
# save trace data and stop analysis #
if SysMgr.outputFile:
SysMgr.saveTraceData(lines)
sys.exit(0)
# Check target thread setting #
if not SysMgr.filterGroup:
SysMgr.filterGroup.insert(0, "")
self.target = []
else:
self.target = SysMgr.filterGroup
# Check root path #
if SysMgr.userEnable:
if SysMgr.rootPath == "":
rootPath = "/"
else:
rootPath = SysMgr.rootPath
SysMgr.printInfo("use '%s' as the sysroot path" % rootPath)
# Register None pos #
self.posData["0"] = dict(self.init_posData)
# get process tree #
SysMgr.getProcTreeInfo()
# start parsing logs #
SysMgr.totalLine = len(lines)
SysMgr.printStat("start analyzing data... [ STOP(Ctrl+c) ]")
# parse logs #
self.parseLines(lines, SysMgr.filterGroup)
# Check whether data of target thread is collected or nothing #
if (
not self.userCallData
and not self.kernelCallData
and len(self.target) > 0
):
if not self.target:
SysMgr.printErr("no collected stack data")
else:
targetStr = ", ".join(self.target)
SysMgr.printErr(
"no collected stack related to '%s'" % targetStr
)
sys.exit(-1)
elif (
SysMgr.userEnable
and len(self.userCallData) == 1
and self.userCallData[0][0] == "0"
):
SysMgr.userEnable = False
if self.target == []:
SysMgr.printWarn("no collected user stack data", True)
else:
targetStr = ", ".join(self.target)
SysMgr.printWarn(
"no collected user stack related to '%s'" % targetStr, True
)
# Get symbols from call address #
SysMgr.printStat("start resolving symbols... [ STOP(Ctrl+c) ]")
self.getSymbols()
# Merge callstacks by symbol and address #
SysMgr.printStat("start summarizing functions... [ STOP(Ctrl+c) ]")
self.mergeStacks()
def __del__(self):
pass
def handleHeapExpand(self, sym, ksym, stackAddr, kstackAddr, size, arg):
addr = arg[0]
time = arg[1]
core = arg[2]
tid = arg[3]
self.userSymData[sym]["heapSize"] += size
self.kerSymData[ksym]["heapSize"] += size
self.heapTable.setdefault(addr, dict(self.init_heapSegData))
self.heapTable[addr]["size"] = size
self.heapTable[addr]["sym"] = sym
self.heapTable[addr]["ksym"] = ksym
self.heapTable[addr]["subStackAddr"] = stackAddr
self.heapTable[addr]["ksubStackAddr"] = kstackAddr
self.heapTable[addr]["time"] = time
self.heapTable[addr]["core"] = core
self.heapTable[addr]["tid"] = tid
def handleHeapReduce(self, size, arg):
addr = arg[0]
subStackIndex = FunctionAnalyzer.symStackIdxTable.index("STACK")
heapExpIndex = FunctionAnalyzer.symStackIdxTable.index("HEAP_EXPAND")
try:
sym = self.heapTable[addr]["sym"]
ksym = self.heapTable[addr]["ksym"]
stackAddr = self.heapTable[addr]["subStackAddr"]
kstackAddr = self.heapTable[addr]["ksubStackAddr"]
self.userSymData[sym]["heapSize"] -= size
self.kerSymData[ksym]["heapSize"] -= size
except:
SysMgr.printWarn("failed to find heap segment to be freed")
return
# Set user stack list #
if self.sort == "sym":
targetStack = self.userSymData[sym]["symStack"]
elif self.sort == "pos":
targetStack = self.userSymData[sym]["stack"]
# Find user stack of symbol allocated this segment #
for val in targetStack:
if id(val[subStackIndex]) == stackAddr:
# Increase heap count of subStack #
val[heapExpIndex] -= size
break
# Set kernel stack list #
kernelTargetStack = self.kerSymData[ksym]["stack"]
# Find kernel stack of symbol allocated this segment #
for val in kernelTargetStack:
if id(val[subStackIndex]) == kstackAddr:
# Increase heap count of subStack #
val[heapExpIndex] -= size
break
self.heapTable.pop(addr)
def handlePageFree(
self,
sym,
ksym,
stackAddr,
kstackAddr,
pageFreeCnt,
pageType,
pfn,
atime,
):
subStackIndex = FunctionAnalyzer.symStackIdxTable.index("STACK")
pageAllocIndex = FunctionAnalyzer.symStackIdxTable.index("PAGE_ALLOC")
pageFreeIndex = FunctionAnalyzer.symStackIdxTable.index("PAGE_FREE")
argIndex = FunctionAnalyzer.symStackIdxTable.index("ARGUMENT")
for cnt in xrange(pageFreeCnt):
pfnv = pfn + cnt
subStackPageInfoIdx = 0
try:
# Decrease page count of symbol allocated page #
# TODO: fix bug about wrong count of pos #
allocSym = self.pageTable[pfnv]["sym"]
allocStackAddr = self.pageTable[pfnv]["subStackAddr"]
allocKernelSym = self.pageTable[pfnv]["ksym"]
allocKernelStackAddr = self.pageTable[pfnv]["ksubStackAddr"]
allocTime = self.pageTable[pfnv]["time"]
self.pageUsageCnt -= 1
self.userSymData[allocSym]["pageCnt"] -= 1
self.kerSymData[allocKernelSym]["pageCnt"] -= 1
if pageType == "USER":
self.userSymData[allocSym]["userPageCnt"] -= 1
self.kerSymData[allocKernelSym]["userPageCnt"] -= 1
subStackPageInfoIdx = 0
elif pageType == "CACHE":
self.userSymData[allocSym]["cachePageCnt"] -= 1
self.kerSymData[allocKernelSym]["cachePageCnt"] -= 1
subStackPageInfoIdx = 1
elif pageType == "KERNEL":
self.userSymData[allocSym]["kernelPageCnt"] -= 1
self.kerSymData[allocKernelSym]["kernelPageCnt"] -= 1
subStackPageInfoIdx = 2
# get page lifetime #
lifeTime = float(atime) - float(allocTime)
# Set user page lifetime #
if lifeTime > self.userSymData[allocSym]["pagePairMax"]:
self.userSymData[allocSym]["pagePairMax"] = lifeTime
if (
self.userSymData[allocSym]["pagePairMin"] == 0
or lifeTime < self.userSymData[allocSym]["pagePairMin"]
):
self.userSymData[allocSym]["pagePairMin"] = lifeTime
self.userSymData[allocSym]["pagePairTotal"] += lifeTime
# Set kernel page lifetime #
if lifeTime > self.kerSymData[allocKernelSym]["pagePairMax"]:
self.kerSymData[allocKernelSym]["pagePairMax"] = lifeTime
if (
self.kerSymData[allocKernelSym]["pagePairMin"] == 0
or lifeTime
< self.kerSymData[allocKernelSym]["pagePairMin"]
):
self.kerSymData[allocKernelSym]["pagePairMin"] = lifeTime
self.kerSymData[allocKernelSym]["pagePairTotal"] += lifeTime
# Set user stack list #
if self.sort == "sym":
targetStack = self.userSymData[allocSym]["symStack"]
elif self.sort == "pos":
targetStack = self.userSymData[allocSym]["stack"]
# Find user stack allocated this page #
for val in targetStack:
if id(val[subStackIndex]) != allocStackAddr:
continue
val[pageAllocIndex] -= 1
val[argIndex][subStackPageInfoIdx] -= 1
# Set user stack list to free this page #
if self.sort == "sym":
subTargetStack = self.userSymData[sym]["symStack"]
elif self.sort == "pos":
subTargetStack = self.userSymData[sym]["stack"]
# Find user stack to free this page #
for sval in subTargetStack:
if id(sval[subStackIndex]) != stackAddr:
continue
if not self.userSymData[allocSym]["pagePair"]:
self.userSymData[allocSym]["pagePair"] = {}
allocCall = ""
freeCall = ""
try:
tsym = val[subStackIndex][0]
allocCall = "%s [%s]" % (
val[subStackIndex][0],
self.userSymData[tsym]["origBin"],
)
for usym in val[subStackIndex][1:]:
allocCall = "%s <- %s [%s]" % (
allocCall,
usym,
self.userSymData[sym]["origBin"],
)
except:
if allocCall == "":
allocCall = "None"
try:
freeCall = "%s [%s]" % (
sym,
self.userSymData[sym]["origBin"],
)
for usym in sval[subStackIndex][1:]:
freeCall = "%s <- %s[%s]" % (
freeCall,
usym,
self.userSymData[sym]["origBin"],
)
except:
if freeCall == "":
freeCall = "None"
pairId = "%s#%s" % (allocCall, freeCall)
try:
self.userSymData[allocSym]["pagePair"][pairId]
except:
self.userSymData[allocSym]["pagePair"][
pairId
] = dict(self.init_glueData)
self.userSymData[allocSym]["pagePairCnt"] += 1
allocator = self.userSymData[allocSym]["pagePair"][
pairId
]
allocator["size"] += 1
if not allocator["valueList"]:
allocator["valueList"] = {}
try:
allocator["valueList"][pageType] += 1
except:
allocator["valueList"][pageType] = 1
break
break
# Set kernel stack list #
kernelTargetStack = self.kerSymData[allocKernelSym]["stack"]
# Find kernel stack allocated this page #
for val in kernelTargetStack:
if id(val[subStackIndex]) != allocKernelStackAddr:
continue
val[pageAllocIndex] -= 1
val[argIndex][subStackPageInfoIdx] -= 1
# Set kernel stack list to free this page #
subTargetStack = self.kerSymData[ksym]["stack"]
# Find kernel stack to free this page #
for sval in subTargetStack:
if id(sval[subStackIndex]) != kstackAddr:
continue
kernelData = self.kerSymData[allocKernelSym]
if not kernelData["pagePair"]:
kernelData["pagePair"] = {}
allocCall = ""
freeCall = ""
try:
allocCall = (
"%s"
% self.posData[val[subStackIndex][0]]["symbol"]
)
for addr in val[subStackIndex][1:]:
allocCall = "%s <- %s" % (
allocCall,
self.posData[addr]["symbol"],
)
except:
if allocCall == "":
allocCall = "None"
try:
freeCall = "%s" % ksym
for addr in sval[subStackIndex]:
freeCall = "%s <- %s" % (
freeCall,
self.posData[addr]["symbol"],
)
except:
if freeCall == "":
freeCall = "None"
pairId = "%s#%s" % (allocCall, freeCall)
try:
kernelData["pagePair"][pairId]
except:
kernelData["pagePair"][pairId] = dict(
self.init_glueData
)
self.kerSymData[allocKernelSym]["pagePairCnt"] += 1
allocator = kernelData["pagePair"][pairId]
allocator["size"] += 1
if not allocator["valueList"]:
allocator["valueList"] = {}
try:
allocator["valueList"][pageType] += 1
except:
allocator["valueList"][pageType] = 1
break
break
self.pageTable.pop(pfnv, None)
except SystemExit:
sys.exit(0)
except:
# this page is allocated before starting profile #
self.pageUnknownFreeCnt += 1
self.userSymData[sym]["unknownPageFreeCnt"] += 1
self.kerSymData[ksym]["unknownPageFreeCnt"] += 1
# Set user stack list #
if self.sort == "sym":
targetStack = self.userSymData[sym]["symStack"]
elif self.sort == "pos":
targetStack = self.userSymData[sym]["stack"]
# Find subStack allocated this page #
for val in targetStack:
if id(val[subStackIndex]) == stackAddr:
val[pageFreeIndex] += 1
break
# Set kernel stack list #
kernelTargetStack = self.kerSymData[ksym]["stack"]
# Find subStack allocated this page #
for val in kernelTargetStack:
if id(val[subStackIndex]) == kstackAddr:
val[pageFreeIndex] += 1
break
continue
def handlePageAlloc(
self,
sym,
ksym,
stackAddr,
kstackAddr,
pageAllocCnt,
pageType,
pfn,
atime,
):
subStackPageInfoIdx = 0
subStackIndex = FunctionAnalyzer.symStackIdxTable.index("STACK")
pageAllocIndex = FunctionAnalyzer.symStackIdxTable.index("PAGE_ALLOC")
argIndex = FunctionAnalyzer.symStackIdxTable.index("ARGUMENT")
# Increase counts of page to be allocated #
self.userSymData[sym]["pageCnt"] += pageAllocCnt
self.kerSymData[ksym]["pageCnt"] += pageAllocCnt
if pageType == "USER":
self.userSymData[sym]["userPageCnt"] += pageAllocCnt
self.kerSymData[ksym]["userPageCnt"] += pageAllocCnt
subStackPageInfoIdx = 0
elif pageType == "CACHE":
self.userSymData[sym]["cachePageCnt"] += pageAllocCnt
self.kerSymData[ksym]["cachePageCnt"] += pageAllocCnt
subStackPageInfoIdx = 1
elif pageType == "KERNEL":
self.userSymData[sym]["kernelPageCnt"] += pageAllocCnt
self.kerSymData[ksym]["kernelPageCnt"] += pageAllocCnt
subStackPageInfoIdx = 2
# Set user stack list #
if self.sort == "sym":
targetStack = self.userSymData[sym]["symStack"]
elif self.sort == "pos":
targetStack = self.userSymData[sym]["stack"]
# Find user stack of symbol allocated this page #
for val in targetStack:
if id(val[subStackIndex]) == stackAddr:
# Increase page count of subStack #
val[argIndex][subStackPageInfoIdx] += pageAllocCnt
break
# Set kernel stack list #
kernelTargetStack = self.kerSymData[ksym]["stack"]
# Find kernel stack of symbol allocated this page #
for val in kernelTargetStack:
if id(val[subStackIndex]) == kstackAddr:
# Increase page count of subStack #
val[argIndex][subStackPageInfoIdx] += pageAllocCnt
break
# Make PTE in page table #
for cnt in xrange(pageAllocCnt):
pfnv = pfn + cnt
subStackPageInfoIdx = 0
try:
# Check whether this page is already allocated #
allocSym = self.pageTable[pfnv]["sym"]
allocStackAddr = self.pageTable[pfnv]["subStackAddr"]
allocKernelSym = self.pageTable[pfnv]["ksym"]
allocKernelStackAddr = self.pageTable[pfnv]["ksubStackAddr"]
# Decrease counts of page already allocated but no free log #
self.pageUsageCnt -= 1
self.userSymData[allocSym]["pageCnt"] -= 1
self.kerSymData[allocKernelSym]["pageCnt"] -= 1
origPageType = self.pageTable[pfnv]["type"]
if origPageType == "USER":
self.userSymData[allocSym]["userPageCnt"] -= 1
self.kerSymData[allocKernelSym]["userPageCnt"] -= 1
subStackPageInfoIdx = 0
elif origPageType == "CACHE":
self.userSymData[allocSym]["cachePageCnt"] -= 1
self.kerSymData[allocKernelSym]["cachePageCnt"] -= 1
subStackPageInfoIdx = 1
elif origPageType == "KERNEL":
self.userSymData[allocSym]["kernelPageCnt"] -= 1
self.kerSymData[allocKernelSym]["kernelPageCnt"] -= 1
subStackPageInfoIdx = 2
# Set user stack list #
if self.sort == "sym":
targetStack = self.userSymData[allocSym]["symStack"]
elif self.sort == "pos":
targetStack = self.userSymData[allocSym]["stack"]
# Find user stack of symbol allocated this page #
for val in targetStack:
if id(val[subStackIndex]) == allocStackAddr:
# Decrease allocated page count of substack #
val[pageAllocIndex] -= 1
val[argIndex][subStackPageInfoIdx] -= 1
break
# Set kernel stack list #
kernelTargetStack = self.kerSymData[allocKernelSym]["stack"]
# Find kernel stack of symbol allocated this page #
for val in kernelTargetStack:
if id(val[subStackIndex]) == allocKernelStackAddr:
# Decrease allocated page count of substack #
val[pageAllocIndex] -= 1
val[argIndex][subStackPageInfoIdx] -= 1
break
except SystemExit:
sys.exit(0)
except:
self.pageTable[pfnv] = dict(self.init_pageLinkData)
self.pageTable[pfnv]["sym"] = sym
self.pageTable[pfnv]["ksym"] = ksym
self.pageTable[pfnv]["type"] = pageType
self.pageTable[pfnv]["subStackAddr"] = stackAddr
self.pageTable[pfnv]["ksubStackAddr"] = kstackAddr
self.pageTable[pfnv]["time"] = atime
def mergeStacks(self):
sym = ""
ksym = ""
stackAddr = 0
kstackAddr = 0
lineCnt = -1
lastIdx = len(self.userCallData)
# Backup page table used previously and Initialize it #
self.oldPageTable = self.pageTable
self.pageTable = {}
# Backup heap table used previously and Initialize it #
self.oldHeapTable = self.heapTable
self.heapTable = {}
subStackIndex = FunctionAnalyzer.symStackIdxTable.index("STACK")
argIndex = FunctionAnalyzer.symStackIdxTable.index("ARGUMENT")
# Merge call data by symbol or address #
for val in self.userCallData:
lineCnt += 1
UtilMgr.printProgress(lineCnt, lastIdx - 1)
pos = val[0]
stack = val[1]
event = val[2]
eventCnt = val[3]
arg = val[4]
"""
Do not merge PAGE_FREE count
because it will be merged with unknownPageFreeCnt
"""
if event == "PAGE_FREE":
savedEventCnt = eventCnt
eventCnt = 0
try:
eventIndex = FunctionAnalyzer.symStackIdxTable.index(event)
except:
eventIndex = FunctionAnalyzer.symStackIdxTable.index("IGNORE")
kernelPos = self.kernelCallData[lineCnt][0]
kernelStack = self.kernelCallData[lineCnt][1]
subStackPageInfo = list(self.init_subStackPageInfo)
targetStack = []
kernelTargetStack = []
# Resolve user symbol #
try:
# No symbol related to last pos #
if self.posData[pos]["symbol"] == "":
self.posData[pos]["symbol"] = pos
sym = pos
else:
sym = self.posData[pos]["symbol"]
except:
continue
# Resolve kernel symbol #
try:
# No symbol related to last pos #
if self.posData[kernelPos]["symbol"] == "":
self.posData[kernelPos]["symbol"] = kernelPos
ksym = kernelPos
else:
ksym = self.posData[kernelPos]["symbol"]
except:
continue
# Make user file table of last pos in stack #
try:
path = self.posData[pos]["binary"]
self.userFileData[path]
except:
self.userFileData[path] = dict(self.init_symData)
# Make user symbol table of last pos in stack #
try:
self.userSymData[sym]
except:
self.userSymData[sym] = dict(self.init_symData)
self.userSymData[sym]["stack"] = []
self.userSymData[sym]["symStack"] = []
self.userSymData[sym]["pos"] = pos
self.userSymData[sym]["origBin"] = self.posData[pos]["origBin"]
# Make kernel symbol table of last pos in stack #
try:
self.kerSymData[ksym]
except:
self.kerSymData[ksym] = dict(self.init_symData)
self.kerSymData[ksym]["stack"] = []
self.kerSymData[ksym]["pos"] = kernelPos
# Set target user stack #
if self.sort == "sym":
tempSymStack = []
# Make temporary symbol stack to merge stacks by symbol #
for addr in stack:
tempSym = self.posData[addr]["symbol"]
# Ignore this function if there is no symbol #
if (
not SysMgr.showAll
and self.posData[addr]["origBin"] == "??"
and (
tempSym == addr
or tempSym == self.posData[addr]["offset"]
or addr == "00c0ffee"
)
):
continue
# No symbol data #
if tempSym == "":
if self.posData[addr]["origBin"] == "??":
tempSym = "%x" % long(
self.posData[addr]["pos"], 16
)
else:
tempSym = "%x" % long(
self.posData[addr]["offset"], 16
)
try:
self.userSymData[tempSym]
except:
self.userSymData[tempSym] = dict(self.init_symData)
self.userSymData[tempSym]["stack"] = []
self.userSymData[tempSym]["symStack"] = []
self.userSymData[tempSym]["pos"] = addr
self.userSymData[tempSym]["origBin"] = self.posData[
addr
]["origBin"]
tempSymStack.append(tempSym)
# Switch input stack to symbol stack #
stack = tempSymStack
targetStack = self.userSymData[sym]["symStack"]
elif self.sort == "pos":
targetStack = self.userSymData[sym]["stack"]
# First user stack related to this symbol #
if not targetStack:
tempList = [0] * len(FunctionAnalyzer.symStackIdxTable)
tempList[eventIndex] = eventCnt
tempList[subStackIndex] = stack
tempList[argIndex] = list(subStackPageInfo)
targetStack.append(tempList)
stackAddr = id(stack)
else:
found = False
# Find same stack by pos in stack list #
for stackInfo in targetStack:
stackSet = set(stack)
subStackSet = set(stackInfo[subStackIndex])
# Found same stack #
if stackSet == subStackSet:
found = True
stackInfo[eventIndex] += eventCnt
stackAddr = id(stackInfo[subStackIndex])
break
# New stack related to this symbol #
if not found:
tempList = [0] * len(FunctionAnalyzer.symStackIdxTable)
tempList[eventIndex] = eventCnt
tempList[subStackIndex] = stack
tempList[argIndex] = list(subStackPageInfo)
targetStack.append(tempList)
stackAddr = id(stack)
# Set target kernel stack #
kernelTargetStack = self.kerSymData[ksym]["stack"]
# First stack related to this symbol #
if not kernelTargetStack:
tempList = [0] * len(FunctionAnalyzer.symStackIdxTable)
tempList[eventIndex] = eventCnt
tempList[subStackIndex] = kernelStack
tempList[argIndex] = list(subStackPageInfo)
kernelTargetStack.append(tempList)
kstackAddr = id(kernelStack)
else:
found = False
for stackInfo in kernelTargetStack:
kerStackSet = set(kernelStack)
kerSubStackSet = set(stackInfo[subStackIndex])
# Found same stack in stack list #
if kerStackSet == kerSubStackSet:
found = True
stackInfo[eventIndex] += eventCnt
kstackAddr = id(stackInfo[subStackIndex])
break
# New stack related to this symbol #
if not found:
tempList = [0] * len(FunctionAnalyzer.symStackIdxTable)
tempList[eventIndex] = eventCnt
tempList[subStackIndex] = kernelStack
tempList[argIndex] = list(subStackPageInfo)
kernelTargetStack.append(tempList)
kstackAddr = id(kernelStack)
# Recover PAGE_FREE count to merge with unknownPageFreeCnt #
if event == "PAGE_FREE":
eventCnt = savedEventCnt
# memory allocation event #
if event == "PAGE_ALLOC":
pageType = arg[0]
pfn = arg[1]
atime = arg[2]
self.handlePageAlloc(
sym,
ksym,
stackAddr,
kstackAddr,
eventCnt,
pageType,
pfn,
atime,
)
# memory free event #
elif event == "PAGE_FREE":
pageType = arg[0]
pfn = arg[1]
atime = arg[2]
self.handlePageFree(
sym,
ksym,
stackAddr,
kstackAddr,
eventCnt,
pageType,
pfn,
atime,
)
# heap expand event #
elif event == "HEAP_EXPAND":
self.handleHeapExpand(
sym, ksym, stackAddr, kstackAddr, eventCnt, arg
)
# heap expand event #
elif event == "HEAP_REDUCE":
self.handleHeapReduce(eventCnt, arg)
# block read event #
elif event == "BLK_READ":
self.userSymData[sym]["blockRdCnt"] += eventCnt
self.kerSymData[ksym]["blockRdCnt"] += eventCnt
# block write event #
elif event == "BLK_WRITE":
self.userSymData[sym]["blockWrCnt"] += eventCnt
self.kerSymData[ksym]["blockWrCnt"] += eventCnt
# lock try event #
elif event == "LOCK_TRY":
self.userSymData[sym]["lockTryCnt"] += eventCnt
self.kerSymData[ksym]["lockTryCnt"] += eventCnt
self.userFileData[path]["lockTryCnt"] += eventCnt
# unlock event #
elif event == "UNLOCK":
self.userSymData[sym]["unlockCnt"] += eventCnt
self.kerSymData[ksym]["unlockCnt"] += eventCnt
self.userFileData[path]["unlockCnt"] += eventCnt
# periodic event such as CPU tick #
elif event == "CPU_TICK":
self.userSymData[sym]["tickCnt"] += 1
self.kerSymData[ksym]["tickCnt"] += 1
self.userFileData[path]["tickCnt"] += 1
# syscall event #
elif event == "SYSCALL":
self.userSymData[sym]["syscallCnt"] += 1
self.kerSymData[ksym]["syscallCnt"] += 1
self.userFileData[path]["syscallCnt"] += 1
# periodic event such as CPU tick #
elif event == "CUSTOM":
if eventCnt > 0:
self.userSymData[sym]["customTotal"] += 1
self.kerSymData[ksym]["customTotal"] += 1
self.userFileData[path]["customTotal"] += 1
self.userSymData[sym]["customCnt"] += eventCnt
self.kerSymData[ksym]["customCnt"] += eventCnt
self.userFileData[path]["customCnt"] += eventCnt
# etc event #
elif event == "IGNORE":
try:
self.ignoreTable[arg]["ignCnt"] += 1
except:
self.ignoreTable[arg] = {"ignCnt": long(1)}
else:
SysMgr.printWarn("failed to recognize event %s" % event)
UtilMgr.deleteProgress()
# Print summary about ignored events #
self.printIgnoreEvents()
def printIgnoreEvents(self):
for idx, value in self.ignoreTable.items():
SysMgr.printWarn(
"ignore %s event %d times" % (idx, value["ignCnt"])
)
def getBinFromServer(self, remoteObj, src, des):
if not remoteObj or remoteObj == "NONE":
SysMgr.printErr(
"wrong remote address, input in the format {IP:PORT}"
)
sys.exit(-1)
# set download command #
req = "DOWNLOAD:%s@%s" % (src, des)
# get connection with server #
self.connObj = NetworkMgr.getServerConn()
if not self.connObj:
return None
# request download command #
NetworkMgr.requestCmd(self.connObj, req)
def getSymbols(self):
binPath = ""
offsetList = []
curIdx = 0
nrNoFile = 0
lastIdx = len(self.posData)
# Set alarm handler to handle hanged addr2line #
signal.signal(signal.SIGALRM, SysMgr.timerHandler)
# Get symbols and source pos #
for idx, value in sorted(
self.posData.items(), key=lambda e: e[1]["binary"], reverse=True
):
curIdx += 1
UtilMgr.printProgress(curIdx, lastIdx)
# Handle thumbcode #
if idx == "00c0ffee":
value["binary"] = "??"
value["origBin"] = "??"
value["symbol"] = "ThumbCode"
continue
# Handle address #
if value["binary"] == "":
# user pos without offset #
if value["symbol"] in ("", "??"):
# TODO: find binary path and symbol of pos #
value["binary"] = "??"
value["origBin"] = "??"
value["symbol"] = idx
continue
# Get symbols from address list of previous binary #
if binPath != value["binary"]:
if binPath != "":
# Get symbols #
if self.getFileSymbolInfo(binPath, offsetList) == -1:
nrNoFile += 1
offsetList = []
if value["offset"] == hex(0):
offsetList.append(idx)
else:
offsetList.append(value["offset"])
# Set new binPath to find symbol from address #
binPath = value["binary"]
# Get binary from server #
if not os.path.isfile(binPath) and SysMgr.remoteServObj:
self.getBinFromServer(
SysMgr.remoteServObj, value["origBin"], binPath
)
# add address to offsetList #
else:
# not relocatable binary #
if value["offset"] == hex(0):
offsetList.append(idx)
# relocatable binary #
else:
offsetList.append(value["offset"])
if self.posData:
UtilMgr.deleteProgress()
# Get symbols and source path from last binary #
if binPath != "":
if self.getFileSymbolInfo(binPath, offsetList) == -1:
nrNoFile += 1
if nrNoFile > 0:
SysMgr.printWarn(
"failed to find total %s binaries to analyze functions"
% nrNoFile,
True,
)
def getFileSymbolInfo(self, binPath, offsetList, onlyFunc=True):
def _updateSymbol(addr, symbol, src, relocated):
if not addr:
return -1
elif symbol == "??":
symbol = addr
# Check whether the file is relocatable or not #
if not relocated:
try:
savedSymbol = self.posData[addr]["symbol"]
except:
return -1
"""
Check whether saved symbol found by
previous addr2line is right #
"""
if (
not savedSymbol
or savedSymbol in ("", addr)
or savedSymbol[0] == "$"
):
self.posData[addr]["symbol"] = symbol
if SysMgr.showAll:
self.posData[addr]["src"] = src
else:
fileIdx = src.rfind("/")
if fileIdx >= 0:
self.posData[addr]["src"] = src[fileIdx + 1 :]
return
inBinArea = False
for idx, value in sorted(
self.posData.items(),
key=lambda e: e[1]["binary"],
reverse=True,
):
if value["binary"] == binPath:
inBinArea = True
if value["offset"] == addr:
savedSymbol = self.posData[idx]["symbol"]
if (
not savedSymbol
or savedSymbol in ("", addr)
or savedSymbol[0] == "$"
):
self.posData[idx]["symbol"] = symbol
if SysMgr.showAll:
self.posData[idx]["src"] = src
else:
fileIdx = src.rfind("/")
if fileIdx >= 0:
self.posData[idx]["src"] = src[
fileIdx + 1 :
]
break
elif inBinArea:
break
# Recognize binary type #
relocated = ElfAnalyzer.isRelocFile(binPath)
# No file exist #
if not os.path.isfile(binPath):
for addr in offsetList:
try:
if not relocated:
self.posData[addr]["symbol"] = "NoFile"
self.posData[addr]["src"] = "NoFile"
else:
for idx, value in sorted(
self.posData.items(),
key=lambda e: e[1]["binary"],
reverse=True,
):
if value["binary"] == binPath and value[
"offset"
] == hex(long(addr, 16)):
self.posData[idx]["symbol"] = "NoFile"
self.posData[idx]["src"] = "NoFile"
break
except SystemExit:
sys.exit(0)
except:
SysMgr.printWarn("failed to find address %s" % addr)
return -1
# check user-mode enabled #
if not SysMgr.userEnable:
return None
# check addr2line path #
if not "ADDR2LINE" in SysMgr.environList:
try:
symbolList = []
binObj = ElfAnalyzer.getObject(binPath)
if not binObj:
return None
for offset in offsetList:
symbol, size = binObj.getSymbolByOffset(
offset, onlyFunc=onlyFunc
)
symbolList.append("??")
_updateSymbol(offset, symbol, "??", relocated)
except SystemExit:
sys.exit(0)
except:
SysMgr.printErr("failed to get symbol from %s" % binPath, True)
return None
# get addr2line path #
addr2linePath = UtilMgr.which("addr2line")
if not addr2linePath:
SysMgr.printErr(
(
"failed to find addr2line to analyze functions, "
"use -q option with ADDR2LINE to set binary path"
)
)
sys.exit(-1)
SysMgr.printInfo(
"use '%s' as the addr2line path" % ", ".join(addr2linePath)
)
else:
for path in SysMgr.environList["ADDR2LINE"]:
if not os.path.isfile(path):
SysMgr.printErr(
"failed to find %s to use addr2line" % path
)
sys.exit(-1)
# get subprocess object #
subprocess = SysMgr.getPkg("subprocess")
for path in SysMgr.environList["ADDR2LINE"]:
# Set addr2line command #
args = [path, "-C", "-f", "-a", "-e", binPath]
# Limit the number of arguments to be passed because of ARG_MAX #
# ARG_MAX = $(getconf PAGE_SIZE)*32 = 131072 #
listLen = len(offsetList)
maxArgLine = 256
offset = 0
timeout = 10
# Get symbol by address of every maxArgLine elements in list #
while offset < listLen:
# Launch addr2line #
try:
workload = offsetList[offset : offset + maxArgLine - 1]
proc = subprocess.Popen(
args + workload,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
)
except SystemExit:
sys.exit(0)
except:
SysMgr.printErr(
"failed to execute %s to pick symbols from binary"
% path
)
sys.exit(-1)
# Increase offset count in address list #
offset += maxArgLine
try:
# Set alarm to handle hanged addr2line #
signal.alarm(timeout)
# Wait for addr2line to finish its job #
proc.wait()
# Cancel alarm after addr2line respond #
signal.alarm(0)
except SystemExit:
sys.exit(0)
except:
SysMgr.printWarn(
"no response of addr2line for %s" % binPath
)
continue
while 1:
# Get return of addr2line #
addr = (
proc.stdout.readline().decode().replace("\n", "")[2:]
)
try:
addr = hex(long(addr, 16)).rstrip("L")
except SystemExit:
sys.exit(0)
except:
pass
symbol = proc.stdout.readline().decode().replace("\n", "")
src = proc.stdout.readline().decode().replace("\n", "")
err = proc.stderr.readline().decode().replace("\n", "")
if err:
SysMgr.printWarn(err[err.find(":") + 2 :])
if _updateSymbol(addr, symbol, src, relocated):
break
def initStacks(self):
self.nowCtx["userLastPos"] = "0"
self.nowCtx["userStack"] = []
self.nowCtx["kerLastPos"] = "0"
self.nowCtx["kerStack"] = []
def swapEvents(self):
tempEvent = self.nowCtx["nowEvent"]
self.nowCtx["nowEvent"] = self.nowCtx["savedEvent"]
self.nowCtx["savedEvent"] = tempEvent
tempCnt = self.nowCtx["nowCnt"]
self.nowCtx["nowCnt"] = self.nowCtx["savedCnt"]
self.nowCtx["savedCnt"] = tempCnt
tempArg = self.nowCtx["nowArg"]
self.nowCtx["nowArg"] = self.nowCtx["savedArg"]
self.nowCtx["savedArg"] = tempArg
def saveFullStack(
self,
kernelPos,
kernelStack,
userPos,
userStack,
targetEvent,
targetCnt,
targetArg,
):
# Save userstack #
self.userCallData.append(
[userPos, userStack, targetEvent, targetCnt, targetArg]
)
# Save kernelstack #
self.kernelCallData.append(
[kernelPos, kernelStack, targetEvent, targetCnt, targetArg]
)
# Save custom event stacks #
if SysMgr.showAll and targetEvent == "CUSTOM":
self.customCallData.append(
[
targetArg[0],
targetArg[1],
self.userCallData[-1],
self.kernelCallData[-1],
]
)
# Save lock event stacks #
if SysMgr.showAll and targetEvent in ("LOCK_TRY", "UNLOCK"):
self.lockCallData.append(
[
targetArg[0],
targetArg[1:],
self.userCallData[-1],
self.kernelCallData[-1],
]
)
# Save syscall event stacks #
if SysMgr.showAll and targetEvent == "SYSCALL":
self.sysCallData.append(
[
targetArg[0],
targetArg[1:],
self.userCallData[-1],
self.kernelCallData[-1],
]
)
def saveEventStack(self, targetEvent, targetCnt, targetArg):
kpos = self.nowCtx["kerLastPos"]
upos = self.nowCtx["userLastPos"]
# save count data #
if targetEvent == "CPU_TICK":
self.periodicEventCnt += 1
elif targetEvent == "PAGE_ALLOC":
self.pageAllocEventCnt += 1
self.pageAllocCnt += targetCnt
self.pageUsageCnt += targetCnt
self.posData[kpos]["pageCnt"] += targetCnt
self.posData[upos]["pageCnt"] += targetCnt
pageType = targetArg[0]
pfn = targetArg[1]
time = targetArg[2]
targetArg = [pageType, pfn, time]
elif targetEvent == "PAGE_FREE":
self.pageFreeEventCnt += 1
self.pageFreeCnt += targetCnt
pageType = targetArg[0]
pfn = targetArg[1]
time = targetArg[2]
targetArg = [pageType, pfn, time]
elif targetEvent == "BLK_READ":
self.blockRdEventCnt += 1
self.blockRdUsageCnt += targetCnt
self.posData[kpos]["blockRdCnt"] += targetCnt
self.posData[upos]["blockRdCnt"] += targetCnt
elif targetEvent == "BLK_WRITE":
self.blockWrEventCnt += 1
self.blockWrUsageCnt += targetCnt
self.posData[kpos]["blockWrCnt"] += targetCnt
self.posData[upos]["blockWrCnt"] += targetCnt
elif targetEvent == "LOCK_TRY":
self.lockTryEventCnt += 1
self.posData[kpos]["lockTryCnt"] += targetCnt
self.posData[upos]["lockTryCnt"] += targetCnt
elif targetEvent == "UNLOCK":
self.unlockEventCnt += 1
self.posData[kpos]["unlockCnt"] += targetCnt
self.posData[upos]["unlockCnt"] += targetCnt
elif targetEvent == "HEAP_EXPAND":
self.heapExpEventCnt += 1
self.heapExpSize += targetCnt
self.posData[kpos]["heapSize"] += targetCnt
self.posData[upos]["heapSize"] += targetCnt
elif targetEvent == "HEAP_REDUCE":
self.posData[kpos]["heapSize"] += targetCnt
self.posData[upos]["heapSize"] += targetCnt
elif targetEvent == "SYSCALL":
nrSyscall = targetArg[0]
self.syscallCnt += 1
try:
self.syscallTable[nrSyscall] += 0
except:
self.syscallTable[nrSyscall] = 1
self.posData[kpos]["syscallCnt"] += targetCnt
self.posData[upos]["syscallCnt"] += targetCnt
elif targetEvent == "CUSTOM":
if targetCnt > 0:
self.customTotal += 1
self.customCnt += targetCnt
self.posData[kpos]["customTotal"] += 1
self.posData[upos]["customTotal"] += 1
self.posData[kpos]["customCnt"] += targetCnt
self.posData[upos]["customCnt"] += targetCnt
else:
pass
# cut stacks by depth #
if SysMgr.funcDepth > 0:
ksize = len(self.nowCtx["kerStack"])
if ksize >= SysMgr.funcDepth:
self.nowCtx["kerLastPos"] = self.nowCtx["kerStack"][
-SysMgr.funcDepth
]
self.nowCtx["kerStack"] = self.nowCtx["kerStack"][
-SysMgr.funcDepth + 1 :
]
usize = len(self.nowCtx["userStack"])
if usize >= SysMgr.funcDepth:
self.nowCtx["userLastPos"] = self.nowCtx["userStack"][
-SysMgr.funcDepth
]
self.nowCtx["userStack"] = self.nowCtx["userStack"][
-SysMgr.funcDepth + 1 :
]
if SysMgr.funcDepth == 1:
self.nowCtx["kerStack"] = []
self.nowCtx["userStack"] = []
try:
# save both stacks #
self.saveFullStack(
self.nowCtx["kerLastPos"],
self.nowCtx["kerStack"],
self.nowCtx["userLastPos"],
self.nowCtx["userStack"],
targetEvent,
targetCnt,
targetArg,
)
except:
SysMgr.printErr("failed to save full stacks", True)
sys.exit(-1)
def saveCallStack(self):
nowCtx = self.nowCtx
# stack of kernel thread #
if (
not SysMgr.userRecordEnable
or nowCtx["prevMode"] != nowCtx["curMode"] == "kernel"
):
if not nowCtx["userStack"] and len(nowCtx["kerStack"]) > 0:
# Set userLastPos to None #
self.nowCtx["userLastPos"] = "0"
self.nowCtx["userStack"].append("0")
if not nowCtx["kerStack"] and len(nowCtx["userStack"]) > 0:
# Set kerLastPos to None #
self.nowCtx["kerLastPos"] = "0"
self.nowCtx["kerStack"].append("0")
# complicated situation ;( #
elif nowCtx["prevMode"] == nowCtx["curMode"]:
# previous user stack loss or nested interval #
if nowCtx["curMode"] == "kernel":
# nested interval #
if nowCtx["nowEvent"] == "CPU_TICK":
# Backup kernel stack #
self.nowCtx["prevKerLastPos"] = nowCtx["kerLastPos"]
self.nowCtx["prevKerStack"] = nowCtx["kerStack"]
# Initialize both stacks #
self.initStacks()
# previous user stack loss #
else:
# Set userLastPos to None #
self.nowCtx["userLastPos"] = "0"
self.nowCtx["userStack"].append("0")
# nested interval #
elif nowCtx["curMode"] == "user":
"""
CORE/0 EVENT0
CORE/0
CORE/0
CORE/0 EVENT1
CORE/0
CORE/0 EVENT2
CORE/0
CORE/0
CORE/0
"""
# Swap nowEvent and savedEvent #
self.swapEvents()
"""
Save both stacks of previous event before
starting to record new kernel stack #
"""
if (len(nowCtx["userStack"]) > 0 and nowCtx["userLastPos"] != "") and (
len(nowCtx["kerStack"]) > 0 and nowCtx["kerLastPos"] != ""
):
# Remove pc in each stacks #
del self.nowCtx["kerStack"][0], self.nowCtx["userStack"][0]
# Check whether there is nested event or not #
if nowCtx["nested"] > 0:
"""
CORE/0 EVENT0
CORE/0
CORE/0
CORE/0 EVENT1
CORE/0 EVENT2
CORE/0
CORE/0
CORE/0
CORE/0
"""
targetEvent = nowCtx["nestedEvent"]
targetCnt = nowCtx["nestedCnt"]
targetArg = nowCtx["nestedArg"]
# Swap nowEvent and savedEvent #
self.swapEvents()
else:
targetEvent = nowCtx["savedEvent"]
targetCnt = nowCtx["savedCnt"]
targetArg = nowCtx["savedArg"]
# Save full stack of previous event #
self.saveEventStack(targetEvent, targetCnt, targetArg)
# Recover previous kernel stack after handling nested event #
if (
nowCtx["prevMode"] == nowCtx["curMode"] == "user"
and nowCtx["prevKerLastPos"] != "0"
):
self.nowCtx["kerLastPos"] = nowCtx["prevKerLastPos"]
self.nowCtx["kerStack"] = nowCtx["prevKerStack"]
self.nowCtx["prevKerLastPos"] = "0"
self.nowCtx["prevKerStack"] = []
else:
self.nowCtx["kerLastPos"] = ""
self.nowCtx["kerStack"] = []
# Initialize user stack #
self.nowCtx["userLastPos"] = ""
self.nowCtx["userStack"] = []
self.nowCtx["nestedEvent"] = ""
self.nowCtx["nestedCnt"] = 0
# On stack recording switch #
self.nowCtx["recStat"] = True
def savePosData(self, pos, path, offset):
if self.nowCtx["nested"] > 0:
targetEvent = self.nowCtx["savedEvent"]
else:
targetEvent = self.nowCtx["nowEvent"]
# Register pos #
try:
self.posData[pos]
if (
path
and path[0] == "/"
and path != self.posData[pos]["origBin"]
):
self.duplicatedPos += 1
"""
SysMgr.printWarn(
"duplicated address %s in both '%s' and '%s'" % \
(pos, path, self.posData[pos]['origBin']))
"""
except:
self.posData[pos] = dict(self.init_posData)
# user mode #
if self.nowCtx["curMode"] == "user":
# Set path #
if path:
self.posData[pos]["origBin"] = path
self.posData[pos]["binary"] = SysMgr.rootPath + path
self.posData[pos]["binary"] = os.path.normpath(
self.posData[pos]["binary"]
)
# Set offset #
if offset:
if ElfAnalyzer.isRelocFile(path):
self.posData[pos]["offset"] = offset
# Save pos #
if not self.nowCtx["userStack"]:
self.nowCtx["userLastPos"] = pos
if targetEvent == "CPU_TICK":
self.posData[pos]["posCnt"] += 1
elif targetEvent == "LOCK_TRY":
self.posData[pos]["lockTryCnt"] += 1
elif targetEvent == "UNLOCK":
self.posData[pos]["unlockCnt"] += 1
self.nowCtx["userStack"].append(pos)
# kernel mode #
elif self.nowCtx["curMode"] == "kernel":
# Save pos #
if not self.nowCtx["kerStack"]:
self.nowCtx["kerLastPos"] = pos
if targetEvent == "CPU_TICK":
self.posData[pos]["posCnt"] += 1
elif targetEvent == "LOCK_TRY":
self.posData[pos]["lockTryCnt"] += 1
elif targetEvent == "UNLOCK":
self.posData[pos]["unlockCnt"] += 1
# Skip pos because it is usercall or no symbol #
elif not SysMgr.showAll and not path:
return
self.posData[pos]["symbol"] = path
self.nowCtx["kerStack"].append(pos)
# wrong mode #
else:
SysMgr.printWarn("wrong current mode %s" % self.nowCtx["curMode"])
# Increase total call count #
if self.nowEvent == "CPU_TICK":
self.posData[pos]["totalCnt"] += 1
def allocHeapSeg(self, tid, size):
try:
self.heapTable[tid + "-ready"]["size"] = size
self.heapTable[tid + "-ready"]["tid"] = tid
self.threadData[tid]["heapSize"] -= size
SysMgr.printWarn(
"overwrite heap segment of %s(%s) at %s"
% (self.threadData[tid]["comm"], tid, SysMgr.dbgEventLine)
)
except:
self.heapTable[tid + "-ready"] = dict(self.init_heapSegData)
self.heapTable[tid + "-ready"]["size"] = size
self.heapTable[tid + "-ready"]["tid"] = tid
def freeHeapSeg(self, addr):
try:
self.heapRedEventCnt += 1
self.heapRedSize += self.heapTable[addr]["size"]
# get tid #
try:
tid = self.heapTable[addr]["tid"]
except:
return
self.threadData[tid]["heapSize"] -= self.heapTable[addr]["size"]
self.heapTable.pop(addr, None)
except:
SysMgr.printWarn(
"failed to free heap segment %s of %s(%s) at %s"
% (
addr,
self.threadData[tid]["comm"],
tid,
SysMgr.dbgEventLine,
)
)
def setHeapSegAddr(self, tid, addr):
try:
self.heapTable[addr] = dict(self.heapTable["%s-ready" % tid])
del self.heapTable["%s-ready" % tid]
except:
SysMgr.printWarn(
"failed to set address of heap segment %s of %s(%s) at %s"
% (
addr,
self.threadData[tid]["comm"],
tid,
SysMgr.dbgEventLine,
)
)
def parseLines(self, lines, desc):
curIdx = 0
lastIdx = len(lines)
# make custom event table #
if SysMgr.customCmd:
for cmd in SysMgr.customCmd:
cmd = cmd.split(":")
if len(cmd) > 1:
self.customEventTable[cmd[0]] = cmd[1]
else:
self.customEventTable[cmd[0]] = None
# make kernel event table #
if SysMgr.kernelCmd:
for cmd in SysMgr.kernelCmd:
cmd = cmd.split(":")
self.customEventTable[cmd[0] + "_enter"] = None
self.customEventTable[cmd[0] + "_exit"] = None
# make user event table #
if SysMgr.userCmd:
for cmd in SysMgr.userCmd:
cmd = cmd.split(":")
self.customEventTable[cmd[0] + "_enter"] = None
self.customEventTable[cmd[0] + "_exit"] = None
# get pid filter by comm in advance #
plist = {}
if SysMgr.groupProcEnable:
for key, value in self.getTargetList(lines).items():
for item in desc:
if item in value["comm"]:
plist[value["tgid"]] = 0
# start parsing logs #
for liter in lines:
curIdx += 1
SysMgr.logSize += len(liter)
SysMgr.curLine += 1
SysMgr.dbgEventLine += 1
ret = self.parse(liter, desc, plist)
UtilMgr.printProgress(curIdx, lastIdx)
# Skip lines before first meaningful event #
if not self.lastCore:
continue
# Set context of current core #
self.nowCtx = self.coreCtx[self.lastCore]
# Save full stack to callData table #
if ret is True:
self.saveCallStack()
elif ret is False:
"""
Ignore this log because its not event or
stack info related to target thread #
"""
self.nowCtx["recStat"] = False
continue
# Save pos into target stack #
elif self.nowCtx["recStat"]:
# decode return value #
(pos, path, offset) = ret
self.savePosData(pos, path, offset)
if lines:
UtilMgr.deleteProgress()
# update finish time #
if self.finishTime == "0":
self.finishTime = self.lastTime
# Save stack of last events per core #
for idx in list(self.coreCtx):
self.lastCore = idx
self.nowCtx = self.coreCtx[idx]
# Recover previous mode #
if SysMgr.userEnable:
self.nowCtx["prevMode"] = "user"
self.nowCtx["curMode"] = "kernel"
self.saveEventParam("IGNORE", 0, 0)
self.nowCtx["nested"] -= 1
self.saveCallStack()
if self.duplicatedPos > 0:
SysMgr.printWarn(
"found %d addresses duplicated" % self.duplicatedPos
)
def getCustomEventValue(self, func, args, cond):
if not cond:
return 1
# set condition #
if ">" in cond:
condVal = cond[cond.find(">") + 1 :]
condOp = ">"
condStr = cond[: cond.find(">")]
elif "<" in cond:
condVal = cond[cond.find("<") + 1 :]
condOp = "<"
condStr = cond[: cond.find("<")]
elif "==" in cond:
condVal = cond[cond.find("==") + 2 :]
condOp = "=="
condStr = cond[: cond.find("==")]
else:
condStr = cond
condOp = None
condVal = None
m = re.match(r"^.+%s=(?P\S+)" % condStr, args)
if not m:
return 0
d = m.groupdict()
value = d["value"]
if not condOp and value:
try:
return long(value)
except:
return 0
elif condOp == ">":
try:
if long(value) > long(condVal):
return long(value)
except:
pass
return 0
elif condOp == "<":
try:
if long(value) < long(condVal):
return long(value)
except:
pass
return 0
elif condOp == "==":
if value == condVal:
return 1
else:
return 0
else:
return 0
def saveEventParam(self, event, count, arg):
# save context #
self.nowCtx["nestedEvent"] = self.nowCtx["savedEvent"]
self.nowCtx["savedEvent"] = self.nowCtx["nowEvent"]
self.nowCtx["nowEvent"] = event
self.nowCtx["nestedCnt"] = self.nowCtx["savedCnt"]
self.nowCtx["savedCnt"] = self.nowCtx["nowCnt"]
self.nowCtx["nowCnt"] = count
self.nowCtx["nestedArg"] = self.nowCtx["savedArg"]
self.nowCtx["savedArg"] = self.nowCtx["nowArg"]
self.nowCtx["nowArg"] = arg
self.nowCtx["nested"] += 1
if self.nowCtx["nested"] > 2:
# self.printDbgInfo()
SysMgr.printWarn(
(
"failed to analyze stack data "
"because of corruption (overflow) at %s\n"
"\tso report the results may differ from actual"
)
% SysMgr.dbgEventLine,
True,
)
def printDbgInfo(self):
data = self.nowCtx
print(
"[%s]" % self.lastCore,
"(now) %s/%s/%s"
% (data["nowEvent"], data["nowCnt"], data["nowArg"]),
"(saved) %s/%s/%s"
% (data["savedEvent"], data["savedCnt"], data["savedArg"]),
"(nested) %s/%s/%s"
% (data["nestedEvent"], data["nestedCnt"], data["nestedArg"]),
"(user) %s/%s" % (data["userLastPos"], len(data["userStack"])),
"(kernel) %s/%s" % (data["kerLastPos"], len(data["kerStack"])),
"(backup) %s/%s"
% (data["prevKerLastPos"], len(data["prevKerStack"])),
"at %s" % SysMgr.dbgEventLine,
)
def parseEventInfo(self, tid, func, args, time, core):
# check core filter #
if (
SysMgr.perCoreList
and long(core) not in SysMgr.perCoreList
and func[0] != "<"
):
self.saveEventParam("IGNORE", 0, func[:-1])
return False
# check fixed event list #
if self.customEventTable and (
func[:-1] in self.customEventTable
or len(
[
event
for event in self.customEventTable
if event.endswith(func[:-1])
]
)
> 0
):
isFixedEvent = False
else:
isFixedEvent = True
# CPU tick event #
# TODO: find shorter periodic event for sampling #
if isFixedEvent and func == "hrtimer_start:":
if "tick_sched_timer" in args:
self.cpuEnabled = True
self.saveEventParam("CPU_TICK", 1, 0)
else:
self.saveEventParam("IGNORE", 0, func[:-1])
return False
# memory allocation event #
elif isFixedEvent and func == "mm_page_alloc:":
m = re.match(
(
r"^\s*page=\s*(?P\S+)\s+pfn=(?P[0-9]+)\s+"
r"order=(?P[0-9]+)\s+migratetype=(?P[0-9]+)\s+"
r"gfp_flags=(?P\S+)"
),
args,
)
if m:
d = m.groupdict()
# check whether it is huge page #
if d["page"] == "(null)":
page = "huge"
else:
page = d["page"]
pfn = long(d["pfn"])
flags = d["flags"]
pageCnt = pow(2, long(d["order"]))
# Increase page count of thread #
self.threadData[tid]["nrPages"] += pageCnt
# Increase page counts of thread #
pageType = None
if (
"NOFS" in flags
or "GFP_WRITE" in flags
or "0x1000000" in flags
):
pageType = "CACHE"
self.threadData[tid]["cachePages"] += pageCnt
elif "USER" in flags:
pageType = "USER"
self.threadData[tid]["userPages"] += pageCnt
else:
pageType = "KERNEL"
self.threadData[tid]["kernelPages"] += pageCnt
# Make PTE in page table #
for cnt in xrange(pageCnt):
pfnv = pfn + cnt
try:
"""
Decrease page count of it's owner \
because this page was already allocated but no free log
"""
ownerTid = self.pageTable[pfnv]["tid"]
self.threadData[ownerTid]["nrPages"] -= 1
origPageType = self.pageTable[pfnv]["type"]
if origPageType == "USER":
self.threadData[ownerTid]["userPages"] -= 1
elif origPageType == "CACHE":
self.threadData[ownerTid]["cachePages"] -= 1
elif origPageType == "KERNEL":
self.threadData[ownerTid]["kernelPages"] -= 1
except:
self.pageTable[pfnv] = dict(self.init_pageData)
self.pageTable[pfnv]["tid"] = tid
self.pageTable[pfnv]["page"] = page
self.pageTable[pfnv]["flags"] = flags
self.pageTable[pfnv]["type"] = pageType
self.pageTable[pfnv]["time"] = time
self.memEnabled = True
self.saveEventParam(
"PAGE_ALLOC", pageCnt, [pageType, pfn, time]
)
else:
self.saveEventParam("IGNORE", 0, func[:-1])
SysMgr.printWarn(
"failed to recognize event %s at %d"
% (func[:-1], SysMgr.dbgEventLine)
)
return False
# memory free event #
elif isFixedEvent and func in (
"mm_page_free:",
"mm_page_free_direct:",
):
m = re.match(
(
r"^\s*page=(?P\S+)\s+pfn=(?P[0-9]+)\s+"
r"order=(?P[0-9]+)"
),
args,
)
if m:
d = m.groupdict()
page = d["page"]
pfn = long(d["pfn"])
pageCnt = pow(2, long(d["order"]))
# Update page table #
origPageType = None
for cnt in xrange(pageCnt):
pfnv = pfn + cnt
try:
owner = self.pageTable[pfnv]["tid"]
origPageType = self.pageTable[pfnv]["type"]
self.threadData[owner]["nrPages"] -= 1
if origPageType == "CACHE":
self.threadData[owner]["cachePages"] -= 1
elif origPageType == "USER":
self.threadData[owner]["userPages"] -= 1
elif origPageType == "KERNEL":
self.threadData[owner]["kernelPages"] -= 1
self.threadData[tid]["nrKnownFreePages"] += 1
self.pageTable.pop(pfnv)
except:
# this page was allocated before starting profile #
self.threadData[tid]["nrUnknownFreePages"] += 1
continue
self.memEnabled = True
self.saveEventParam(
"PAGE_FREE", pageCnt, [origPageType, pfn, time]
)
return False
SysMgr.printWarn(
"failed to recognize event %s at %d"
% (func[:-1], SysMgr.dbgEventLine)
)
self.saveEventParam("IGNORE", 0, func[:-1])
return False
# syscall / heap / lock events #
elif isFixedEvent and func == "sys_enter:":
m = re.match(r"^\s*NR (?P[0-9]+) (?P.+)", args)
if m:
b = m.groupdict()
num = long(b["nr"])
self.threadData[tid]["lastNrSyscall"] = num
# syscall event #
if SysMgr.sysEnable:
self.sysEnabled = True
syscallList = SysMgr.syscallList
if not syscallList or num in syscallList:
args = b["args"][1:-1]
self.threadData[tid]["nrSyscall"] += 1
# set syscall table #
if not self.threadData[tid]["syscallTable"]:
self.threadData[tid]["syscallTable"] = {}
try:
self.threadData[tid]["syscallTable"][num] += 1
except:
self.threadData[tid]["syscallTable"][num] = 1
self.saveEventParam(
"SYSCALL", 1, [num, args, time, core, tid]
)
return False
# heap increasement event #
elif num == ConfigMgr.getMmapId():
self.heapEnabled = True
try:
size = long(b["args"].split(",")[1], 16)
# just brk call to check data segment address #
if size == 0:
pass
self.threadData[tid]["heapSize"] += size
except:
self.saveEventParam("IGNORE", 0, func[:-1])
return False
# make heap segment tid-ready #
self.allocHeapSeg(tid, size)
self.saveEventParam("IGNORE", 0, func[:-1])
return False
# heap decreasement event #
elif num == SysMgr.getNrSyscall("sys_munmap"):
self.heapEnabled = True
try:
addr = long(b["args"][1:].split(",")[0], 16)
size = self.heapTable[addr]["size"]
# remove heap segment #
self.freeHeapSeg(addr)
self.saveEventParam(
"HEAP_REDUCE", size, [addr, time, core, tid]
)
return False
except:
pass
# lock event #
elif num == SysMgr.getNrSyscall("sys_futex"):
n = re.match(
(
r"^\s*(?P\S+), (?P\S+), "
r"(?P\S+), (?P\S+),"
),
b["args"],
)
if n:
l = n.groupdict()
FUTEX_CMD_MASK = ~(128 | 256)
# FUTEX_PRIVATE_FLAG: 128, FUTEX_CLOCK_REALTIME: 256 #
maskedOp = long(l["op"], base=16) & FUTEX_CMD_MASK
addr = l["uaddr"][1:]
try:
event = ConfigMgr.FUTEX_TYPE[maskedOp]
except:
event = "LOCK"
# lock_pi #
if event in ("FUTEX_LOCK_PI", "FUTEX_TRYLOCK_PI"):
self.lockEnabled = True
self.threadData[tid]["nrLockTry"] += 1
self.saveEventParam(
"LOCK_TRY", 1, [event, addr, time, core, tid]
)
return False
# wait #
elif event in (
"FUTEX_WAIT",
"FUTEX_WAIT_REQUEUE_PI",
"FUTEX_WAIT_BITSET",
):
self.lockEnabled = True
self.threadData[tid]["nrLockTry"] += 1
self.saveEventParam(
"LOCK_TRY", 1, [event, addr, time, core, tid]
)
return False
# unlock #
elif event == "FUTEX_UNLOCK_PI":
self.lockEnabled = True
self.threadData[tid]["nrUnlock"] += 1
self.saveEventParam(
"UNLOCK", 1, [event, addr, time, core, tid]
)
return False
else:
SysMgr.printWarn(
"failed to recognize event %s at %d"
% (func[:-1], SysMgr.dbgEventLine)
)
self.saveEventParam("IGNORE", 0, func[:-1])
return False
# syscall / heap events #
elif isFixedEvent and func == "sys_exit:":
m = re.match(r"^\s*NR (?P\S+) = (?P.+)", args)
if m:
b = m.groupdict()
nr = long(b["nr"])
# handle wrong syscall number #
if nr < 0:
if self.threadData[tid]["lastNrSyscall"] >= 0:
nr = self.threadData[tid]["lastNrSyscall"]
# heap increasement event #
if nr == ConfigMgr.getMmapId():
self.heapEnabled = True
addr = long(b["ret"])
# rename heap segment from tid-ready to addr #
self.setHeapSegAddr(tid, addr)
try:
size = self.heapTable[addr]["size"]
self.saveEventParam(
"HEAP_EXPAND", size, [addr, time, core, tid]
)
return False
except:
pass
# heap decreasement event #
elif nr == SysMgr.getNrSyscall("sys_brk"):
self.heapEnabled = True
addr = long(b["ret"])
try:
pid = self.threadData[tid]["tgid"]
if pid.startswith("-"):
pid = SysMgr.savedProcTree[tid]
self.threadData[pid]
except:
pid = tid
try:
self.threadData[pid]["lastBrk"]
if addr > self.threadData[pid]["lastBrk"]:
size = addr - self.threadData[pid]["lastBrk"]
self.threadData[pid]["heapSize"] += size
self.saveEventParam(
"HEAP_EXPAND", size, [addr, time, core, tid]
)
return False
except:
self.threadData[pid]["lastBrk"] = addr
else:
SysMgr.printWarn(
"failed to recognize event %s at %d"
% (func[:-1], SysMgr.dbgEventLine)
)
self.saveEventParam("IGNORE", 0, func[:-1])
return False
# block request event #
elif isFixedEvent and func == "block_bio_queue:":
m = re.match(
(
r"^\s*(?P[0-9]+),(?P[0-9]+)\s*"
r"(?P\S+)\s*(?P\S+)\s+\+\s+"
r"(?P