Import of the watch repository from Pebble

This commit is contained in:
Matthieu Jeanson 2024-12-12 16:43:03 -08:00 committed by Katharine Berry
commit 3b92768480
10334 changed files with 2564465 additions and 0 deletions

339
third_party/duma/COPYING-GPL vendored Normal file
View file

@ -0,0 +1,339 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
675 Mass Ave, Cambridge, MA 02139, 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 Library 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
Appendix: 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.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) 19yy <name of author>
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., 675 Mass Ave, Cambridge, MA 02139, 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) 19yy 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 Library General
Public License instead of this License.

504
third_party/duma/COPYING-LGPL vendored Normal file
View file

@ -0,0 +1,504 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
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 and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, 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 library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete 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 distribute a copy of this License along with the
Library.
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 Library or any portion
of it, thus forming a work based on the Library, 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) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
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 Library, 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 Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you 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.
If distribution of 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 satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be 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.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library 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.
9. 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 Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
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 with
this License.
11. 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 Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library 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 Library.
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.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library 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.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser 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 Library
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 Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
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
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "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
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. 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 LIBRARY 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
LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), 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 Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of the
ordinary General Public License).
To apply these terms, attach the following notices to the library. 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.
<one line to give the library's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!

506
third_party/duma/LICENSE vendored Normal file
View file

@ -0,0 +1,506 @@
Copyright (C) 2006 Michael Eddington <meddington@gmail.com>
Copyright (C) 2002-2008 Hayati Ayguen <h_ayguen@web.de>, Procitec GmbH
Copyright (C) 1987-1999 Bruce Perens <bruce@perens.com>
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
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 and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, 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 library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete 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 distribute a copy of this License along with the
Library.
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 Library or any portion
of it, thus forming a work based on the Library, 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) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
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 Library, 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 Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you 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.
If distribution of 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 satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be 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.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library 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.
9. 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 Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
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 with
this License.
11. 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 Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library 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 Library.
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.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library 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.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser 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 Library
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 Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
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
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "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
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. 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 LIBRARY 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
LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), 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 Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of the
ordinary General Public License).
To apply these terms, attach the following notices to the library. 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.
<one line to give the library's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!

716
third_party/duma/README.txt vendored Normal file
View file

@ -0,0 +1,716 @@
Title: README
D.U.M.A. - Detect Unintended Memory Access - A Red-Zone memory allocator:
DESCRIPTION:
DUMA helps you detect two common programming bugs:
software that overruns the boundaries of a malloc() memory allocation, and
software that touches a memory allocation that has been released by free().
Unlike other malloc() debuggers, DUMA will detect read accesses as well as
writes, and it will pinpoint the exact instruction that causes an error.
It has been in use at Pixar since 1987, and at many other sites for years.
DUMA uses the virtual memory hardware of your computer to place an inaccessible
memory page immediately after (or before, at the user's option) each memory
allocation. When software reads or writes this inaccessible page, the hardware
issues a segmentation fault, stopping the program at the offending instruction.
It is then trivial to find the erroneous statement using your favorite
debugger. In a similar manner, memory that has been released by free() is made
inaccessible, and any code that touches it will get a segmentation fault.
Simply linking your application with libduma.a will allow you to detect most,
but not all, malloc buffer overruns and accesses of free memory. If you want
to be reasonably sure that you've found all bugs of this type, you'll have to
read and understand the rest of this man page.
USAGE:
Link your program with the library libduma.a. Make sure you are not linking
with '-lmalloc', '-lmallocdebug', or with other malloc-debugger or
malloc-enhancer libraries. You can only use one at a time.
If your system administrator has installed DUMA for public use, you'll be able
to use the '-lduma' argument to the linker, otherwise you'll have to put the
path-name for libduma.a in the linker's command line.
You can also use dynamic linking. If you're using a Bourne shell, the statement
'export LD_PRELOAD=libduma.so.0.0' will cause DUMA to be loaded to run all
dynamic executables.
The command 'duma.sh <command>' runs a single command under DUMA.
Some systems will require special arguments to the linker to assure that you
are using the DUMA malloc() and not the one from your C library.
Run your program using a debugger. It's easier to work this way than to create
a core file and post-mortem debug it. DUMA can create huge core files, and some
operating systems will thus take minutes simply to dump core! Some operating
systems will not create usable core files from programs that are linked with
DUMA.
If your program has one of the errors detected by DUMA, it will get a
segmentation fault (SIGSEGV) at the offending instruction. Use the debugger to
locate the erroneous statement, and repair it.
GLOBAL AND ENVIRONMENT VARIABLES:
DUMA has several configuration switches that can be enabled via
the shell environment. These switches change what bugs DUMA will detect,
so it's important that you know how to use them.
In older versions of DUMA you could set the value of
global integer variables (using a debugger). In actual DUMA versions most
of the global variables don't exist any more: they changed to thread local
variables defined in structures. Instead you can call macro function to set
some variables - but not from debugger!
You can use the gdb command 'set environment variable value' to set shell
environment variables only for the program you are going to debug. This is
useful especially if you are using the shared DUMA library.
DUMA_ALIGNMENT - This is an integer that specifies the alignment for any memory
allocations that will be returned by malloc(), calloc(), and realloc().
The value is specified in bytes, thus a value of 4 will cause memory to be
aligned to 32-bit boundaries unless your system doesn't have a 8-bit
characters. DUMA_ALIGNMENT is set to the minimum required alignment specific
to your environment by default. The minimum required alignment is detected by
createconf and stored in the file duma_config.h.
If your program requires that allocations be aligned to 64-bit boundaries
you'll have to set this value to 8. This is the case when compiling with the
'-mips2' flag on MIPS-based systems such as those from SGI. For some
architectures the default is defined to even more - x86_64 uses alignment to
16 bytes by default.
DUMA internally uses a smaller value if the requested memory size is smaller
than the alignment value: the next smaller power of 2 is used.
Thus allocating blocks smaller than DUMA_ALIGNMENT may result into smaller
alignments - for example when allocating 3 bytes, they would be aligned to 2
byte boundary. This allows better detection of overrun.
For this reason, you will sometimes want to set DUMA_ALIGNMENT to 1 (no
alignment), so that you can detect overruns of less than your CPU's word
size. Be sure to read the section 'WORD-ALIGNMENT AND OVERRUN DETECTION' in
this manual page before you try this.
To change this value, set DUMA_ALIGNMENT in the shell environment to an
integer value, or call the macro function DUMA_SET_ALIGNMENT() from your
code.
You don't need to change this setting, if you just need bigger alignment for
some special buffers. In this case you may use the function
memalign(alignment, userSize).
DUMA_PROTECT_BELOW - DUMA usually places an inaccessible page immediately after
each memory allocation, so that software that runs past the end of the
allocation will be detected. Setting DUMA_PROTECT_BELOW to 1 causes DUMA to
place the inaccessible page before the allocation in the address space, so
that under-runs will be detected instead of over-runs.
To change this value, set DUMA_PROTECT_BELOW in the shell environment to an
integer value, or call the macro function DUMA_SET_PROTECT_BELOW() from your
code.
DUMA_SKIPCOUNT_INIT - DUMA usually does its initialization with the first
memory allocation. On some systems this may collide with initialization of
pthreads or other libaries and produce a hang. To get DUMA work even in these
situations you can control (with this environment variable) after how many
allocations the full internal initialization of DUMA is done. Default is 0.
DUMA_REPORT_ALL_LEAKS - DUMA usually reports only memory leaks where the source
filename with line number of the allocating instruction is known. Setting this
variable to 1 in shell environment reports all memory leaks.
The default is 0 to avoid reporting of irrelevant memory leaks from
system/compiler environment: there are many standard libraries leaking memory,
which by default is no real problem as the system frees up all memory on
program exit.
DUMA_FILL - When set to a value between 0 and 255, every byte of allocated
memory is initialized to that value. This can help detect reads of
uninitialized memory. When set to -1, DUMA does not initialise memory on
allocation. But some memory is filled with zeroes (the operating system
default on most systems) and some memory will retain the values written to
it during its last use.
Per default DUMA will initialise all allocated bytes to 255 (=0xFF).
To change this value, set DUMA_FILL in the shell environment to an
integer value, or call the macro function DUMA_SET_FILL() from your
code.
DUMA_SLACKFILL - As DUMA internally allocates memory in whole pages, there
retains an unused and unprotectable piece of memory: the slack or no mans
land. Per default DUMA will initialise this area to 170 (=0xAA), which
is 10101010 in binary representation.
To change this value, set DUMA_SLACKFILL in the shell environment to an
integer value.
DUMA automatically checks this area, the no mans land, at deallocation.
You can manually induce a check with the macro function DUMA_CHECK() for
one memory block. With the macro function DUMA_CHECKALL() all memory blocks
get checked.
DUMA_CHECK_FREQ - First see DUMA_SLACKFILL abover for definition of no mans
land. Checking the integrity of the no mans land costs performance. This is
why this is usually done only at deallocation of a memory block. Set this
variable to let DUMA check all memory blocks no mans land every <value>.th
allocation or deallocation. Set this variable to 1, to let DUMA check at
each allocation and deallocation.
Per default the value 0 is used, which means to check only at deallocation.
DUMA_ALLOW_MALLOC_0 - Memory allocation of size zero is ANSI conform. But
often this is the result of a software bug. For this reason DUMA may trap
such calls to malloc() with size zero. I leave this option disabled by
default, but you are free to trap these calls setting the DUMA_ALLOC_MALLOC_0
in the shell environment to an integer value.
DUMA_MALLOC_0_STRATEGY - This environment variable controls DUMA's behaviour
on malloc(0):
0 - like having former ALLOW_MALLOC_0 = 0 ==> abort program with segfault
1 - return NULL pointer
2 - return always the same pointer to some protected page
3 - return mid address of a unique protected page (=default)
ATTENTION: only 1 and 3 are ANSI conform. But value 1 will break most
programs, cause value 3 strategy most system libraries use/implement.
All returned pointers can be passed to free().
DUMA_NEW_0_STRATEGY - This environment variable controls DUMA's behaviour
on C++ operator new with size zero:
2 - return always the same pointer to some protected page
3 - return mid address of a unique protected page (=default)
ATTENTION: only 3 is standard conform. Value 2 may break some but will
work for most programs. With value 2 you may reduce the memory consumption.
DUMA_MALLOC_FAILEXIT - Many programs do not check for allocation failure. This
often leads to delayed errors, no more understandable. Set this variable to a
positive integer in the shell environment to exit the program immediately
when memory allocation fails. This option is set by default.
DUMA_PROTECT_FREE - DUMA usually returns free memory to a pool from which it
may be re-allocated. If you suspect that a program may be touching free
memory, set DUMA_PROTECT_FREE shell environment to -1. This is the default
and will cause DUMA not to re-allocate any memory.
For programs with many allocations and deallocations this may lead to the
consumption of the full address space and thus to the failure of malloc().
To avoid such failures you may limit the amount of protected deallocated
memory by setting DUMA_PROTECT_FREE to a positive value. This value in kB
will be the limit for such protected free memory.
A value of 0 will disable protection of freed memory.
DUMA_MAX_ALLOC - This shell environment variable limits the total memory print
of a program. This is another way to indirectly limit the sum of freed
protected memory (see DUMA_PROTECT_FREE). By default there is no limit (=-1).
A positive value is interpreted in kB, which stands for the sum of allocated
and freed protected memory.
DUMA_FREE_ACCESS - This is a debugging enhancer to catch deallocation of a
memory block using watch expressions. DUMA does a write access to the first
byte, which may lead a debugger to stop on a watch expression. You have to
enable this by setting the shell environment variable to non zero.
Default is disabled.
DUMA_SHOW_ALLOC - Set this shell environment variable to non-zero to let DUMA
print all allocations and deallocations to the console. Although this
generates a lot of messages, this option can be useful to detect inefficient
code containing many (de)allocations. This is switched off by default.
DUMA_SUPPRESS_ATEXIT - Set this shell environment variable to non-zero when
DUMA should skip the installation of its exit handler. The exit handler is
called at the end of the main program and checks for memory leaks, so the
handler's installation should *usually* not be suppressed. One reason for
doing so regardless are some buggy environments, where calls to the standard
C library's atexit()-function hangs.
DUMA_DISABLE_BANNER - Set this shell environment variable to non-zero to
suppress the usual startup message on console. Default is 0.
DUMA_OUTPUT_DEBUG - Set this shell environment variable to non-zero to output
all DUMA messages to the debugging console. This option is only available
on Windows and is off by default.
DUMA_OUTPUT_STDOUT - Set this shell environment variable to non-zero to output
all DUMA messages to STDOUT. This option is off by default.
DUMA_OUTPUT_STDERR - Set this shell environment variable to non-zero to output
all DUMA messages to STDERR. This option is on by default.
DUMA_OUTPUT_FILE - Set this shell environment variable to a filename where all
DUMA messages should be written to. This option is off by default.
DUMA_OUTPUT_STACKTRACE - Set this shell environment variable to non-zero to
output a stacktrace of the allocation that is not free'd. This option is
available only on Windows and is off by default. This option also requires a map
file generated by the linker.
DUMA_OUTPUT_STACKTRACE_MAPFILE - Set this shell environment variable to the map
file, when it isn't found. This is very usefull when using detours version of
DUMA. This option is available only on Windows.
WORD-ALIGNMENT AND OVERRUN DETECTION:
There is a conflict between the alignment restrictions that malloc() operates
under and the debugging strategy used by DUMA. When detecting overruns, DUMA
malloc() allocates two or more virtual memory pages for each allocation. The
last page is made inaccessible in such a way that any read, write, or execute
access will cause a segmentation fault. Then, DUMA malloc() will return an
address such that the first byte after the end of the allocation is on the
inaccessible page. Thus, any overrun of the allocation will cause a
segmentation fault.
It follows that the address returned by malloc() is the address of the
inaccessible page minus the size of the memory allocation. Unfortunately,
malloc() is required to return word-aligned allocations, since many CPUs can
only access a word when its address is aligned. The conflict happens when
software makes a memory allocation using a size that is not a multiple of the
word size, and expects to do word accesses to that allocation. The location of
the inaccessible page is fixed by hardware at a word-aligned address. If DUMA
malloc() is to return an aligned address, it must increase the size of the
allocation to a multiple of the word size.
In addition, the functions memalign() and valloc() must honor explicit
specifications on the alignment of the memory allocation, and this, as well can
only be implemented by increasing the size of the allocation. Thus, there will
be situations in which the end of a memory allocation contains some padding
space, and accesses of that padding space will not be detected, even if they
are overruns.
DUMA provides the variable DUMA_ALIGNMENT so that the user can control the
default alignment used by malloc(), calloc(), and realloc(). To debug overruns
as small as a single byte, you can set DUMA_ALIGNMENT to one. This will result
in DUMA malloc() returning unaligned addresses for allocations with sizes that
are not a multiple of the word size. This is not a problem in most cases,
because compilers must pad the size of objects so that alignment restrictions
are honored when storing those objects in arrays. The problem surfaces when
software allocates odd-sized buffers for objects that must be word-aligned. One
case of this is software that allocates a buffer to contain a structure and a
string, and the string has an odd size (this example was in a popular TIFF
library). If word references are made to un-aligned buffers, you will see a bus
error (SIGBUS) instead of a segmentation fault. The only way to fix this is to
re-write the offending code to make byte references or not make odd-sized
allocations, or to set DUMA_ALIGNMENT to the word size.
Another example of software incompatible with DUMA_ALIGNMENT < word-size
is the strcmp() function and other string functions on SunOS (and probably
Solaris), which make word-sized accesses to character strings, and may attempt
to access up to three bytes beyond the end of a string. These result in a
segmentation fault (SIGSEGV). The only way around this is to use versions of
the string functions that perform byte references instead of word references.
CATCHING THE ERRONEOUS LINE:
To get the line in your sources, where an error occurs, go as following:
1. Compile your program with debugging information
and statically linked to DUMA.
2. Start your program from debugger f.e. with 'gdb <program>'
3. Set program environment variables like 'set environment DUMA_PROTECT_BELOW 1'
4. set your program arguments with 'set args ..'
5. Run and wait for the segmentation fault
alternatively
1. Compile your program (with debugging information) without DUMA.
2. Set 'ulimit -c unlimited' to get core files
3. Start your program, choose one of following options
a) Start your program (linked statically with DUMA)
b) Start your program with duma.sh <your_program>
4. Wait for a segmentation fault. this should have created a core[.<pid>]
file. You can get into a debugger f.e. with 'gdb <program> -c <core file>'
INSTRUCTIONS FOR DEBUGGING YOUR PROGRAM:
1. Link with libduma.a as explained above.
2. Run your program in a debugger and fix any overruns or accesses
to free memory.
3. Quit the debugger.
4. Set DUMA_PROTECT_BELOW = 1 in the shell environment.
5. Repeat step 2, this time repairing underruns if they occur.
6. Quit the debugger.
7. Read the restrictions in the section on
alternatively
read and install gdbinit.rc as ~/.gdbinit
if you are using a GNU gdb based debugger
WORD-ALIGNMENT AND OVERRUN DETECTION:
See if you can set DUMA_ALIGNMENT to 1 and repeat step 2. Sometimes this will
be too much work, or there will be problems with library routines for which you
don't have the source, that will prevent you from doing this.
MEMORY USAGE AND EXECUTION SPEED:
Since DUMA uses at least two virtual memory pages for each of its allocations,
it's a terrible memory hog. I've sometimes found it necessary to add a swap
file using swapon(8) so that the system would have enough virtual memory to
debug my program. Also, the way we manipulate memory results in various cache
and translation buffer entries being flushed with each call to malloc or free.
The end result is that your program will be much slower and use more resources
while you are debugging it with DUMA.
The Linux kernel also limits the number of different page mappings per process.
Have a look for
/proc/sys/vm/max_map_count
f.e. under
http://www.redhat.com/docs/manuals/enterprise/RHEL-4-Manual/en-US/Reference_Guide/s3-proc-sys-vm.html
You may have to increase this value to allow debugging with DUMA with a
command like:
"sudo sysctl -w vm.max_map_count=1000000"
Don't leave libduma.a linked into production software! Use it only for
debugging. See section 'COMPILATION NOTES FOR RELEASE/PRODUCTION' below.
MEMORY LEAK DETECTION:
All memory allocation is protocoled from DUMA together with the filename and
linenumber of the calling function. The atexit() function checks if each
allocated memory block was freed. To disable leak detection add the
preprocessor definition 'DUMA_SO_NO_LEAKDETECTION' or
'DUMA_LIB_NO_LEAKDETECTION' to DUMA_OPTIONS in Makefile.
If a leak is reported without source filename and line number but is
reproducible with the same pointer, set a conditional breakpoint on the
function 'void * duma_alloc_return( void * address)'
f.e. with gdb command 'break duma_alloc_return if address==0x123'
C++ MEMORY OPERATORS AND LEAK DETECTION:
Macros for "new" and "delete" are defined in dumapp.h. These macros give
filename and linenumber of the calling functions to DUMA, thus allowing the
same leak detection reports as for malloc and free. 'dumapp.h' needs to be
included from your source file(s).
For disabling the C++ new/delete/new[] and delete[] operators, add the
preprocessor definition 'DUMA_NO_CPP_SUPPORT' to DUMA_OPTIONS in Makefile.
DEFINITION OF OWN MEMBER NEW/DELETE OPERATORS:
Definition of own member new/delete operators for a class will fail cause the
new/delete keywords are defined as macros from DUMA. You will have to undefine
DUMA's macros with following line:
:#include "noduma.h"
Then you have to call DUMA's operators directly inside your own definition.
For using DUMA's C++ operators without having the preprocessor macros defined,
following syntax can be used:
(start code)
// const char * file or __FILE__ macro
// int line or __LINE__ macro
ptr = new(file,line) type; // scalar new throwing bad_alloc() on error
ptr = new(std::nothrow,file,line) type; // scalar new returning 0 on error
operator delete(ptr,file,line); // scalar delete
ptr = new(file,line) type[n]; // vector new throwing bad_alloc() on error
ptr = new(std::nothrow,file,line) type[n]; // vector new returning 0 on error
operator delete[](ptr, file,line); // vector delete
(end code)
The default syntax without file/line info can be used, too.
PREPACKAGED RPM FILES FOR REDHAT & CO:
You can download prepackaged .rpm files for RedHat, Fedora Core and similar
systems from
http://dries.ulyssis.org/apt/packages/duma/info.html
Dries Verachtert <dries@ulyssis.org> wrote the .spec file.
COMPILATION NOTES FOR VISUAL C++:
Here some Compilation Notes for your Application in Debug Mode
for the Microsoft Visual C++ (v6) Compiler:
1) Don't use Program Database for "Edit and Continue":
Project-Options -> C++ -> General -> Debug-Info
2) Don't use the "multithreaded-dll" runtime library:
Project-Options -> C++ -> Code Generation -> Runtime library
3) Switch off incremental linking
Project-Options -> Linker -> General
4) Switch off precompiled headers:
Project-Options -> C++ -> Precompiled Headers
5) Add following Linker option "/FORCE:MULTIPLE"
Project-Options -> Linker -> General
The labels may differ a bit cause i'm using the german version:
Options in german language:
1) Projekteinstellungen -> C++ -> Kategorie =Allgemein
-> Debug-Info =Programmdatenbank
2) Projekteinstellungen -> C++ -> Kategorie =Codegeneration
-> Laufzeitbibliothek anpassen (Release/Debug),
nicht die DLL-Variante verwenden
3) Projekteinstellungen -> Linker -> Kategorie =Allgemein
- Inkrementelles Binden =Aus
4) Projekteinstellungen -> Linker -> Projekt Optionen
"/FORCE:MULTIPLE" unten eingeben
Now everything you have to do is to set a dependency to "duma" from your
application.
COMPILATION NOTES FOR RELEASE/PRODUCTION:
Set the preprocessor definition
#define DUMA_NO_DUMA
in your Makefiles to disable DUMA usage and don't link with DUMA library.
With DUMA_NO_DUMA-definition all DUMA macro functions get defined but do
nothing. This way you don't have to change your code for release compilation
even when using special DUMA macros.
WARNINGS:
I have tried to do as good a job as I can on this software, but I doubt that it
is even theoretically possible to make it bug-free. This software has no
warranty. It will not detect some bugs that you might expect it to detect, and
will indicate that some non-bugs are bugs.
FILES:
/dev/zero: Source of memory pages (via mmap(2)).
SEE ALSO:
malloc(3), mmap(2), mprotect(2), swapon(8)
DIAGNOSTICS:
Segmentation Fault: Examine the offending statement for violation of the
boundaries of a memory allocation.
Bus Error: See the section on WORD-ALIGNMENT AND OVERRUN DETECTION in this
manual page.
BUGS:
My explanation of the alignment issue could be improved.
Some Sun systems running SunOS 4.1 were reported to signal an access to a
protected page with 'SIGBUS' rather than 'SIGSEGV', I suspect this is an
undocumented feature of a particular Sun hardware version, not just the
operating system. On these systems, dumatest will fail with a bus error until
you modify the Makefile to define PAGE_PROTECTION_VIOLATED_SIGNAL as SIGBUS.
There are, without doubt, other bugs and porting issues. Please contact me via
e-mail if you have any bug reports, ideas, etc.
OTHER ALTERNATIVE/ADDITIONAL DEBUGGING SOFTWARE/TOOLS:
GCC
option -Warray-bounds up from gcc 4.3
options -fmudflap -fmudflapth -fmudflapir up from gcc 4.0
See http://gcc.gnu.org/
See http://gcc.gnu.org/wiki/Mudflap_Pointer_Debugging
IBM Stack Smashing Protector aka Pro Police
it is a GCC (Gnu Compiler Collection) extension for protecting applications
from stack-smashing attacks. Applications written in C will be protected by
the method that automatically inserts protection code into an application at
compilation time. The protection is realized by buffer overflow detection and
the variable reordering feature to avoid the corruption of pointers. The basic
idea of buffer overflow detection comes from StackGuard system.
See http://www.trl.ibm.com/projects/security/ssp/
Checkergcc
a modified version of the GNU C Compiler that instruments all memory
references, is available on Linux systems and where GCC is used. It performs
some of the same tasks as Purify, but only on code that it has compiled.
Valgrind
Valgrind is an award-winning suite of tools for debugging and profiling Linux
programs. With the tools that come with Valgrind, you can automatically detect
many memory management and threading bugs, avoiding hours of frustrating
bug-hunting, making your programs more stable. You can also perform detailed
profiling, to speed up and reduce memory use of your programs.
The Valgrind distribution currently includes four tools: a memory error
detector, a cache (time) profiler, a call-graph profiler, and a heap (space)
profiler. It runs on the following platforms: X86/Linux, AMD64/Linux,
PPC32/Linux, PPC64/Linux.
See http://valgrind.org/
Pageheap.exe
Another alternative to using duma on Windows (XP, 2000, Server 2003) is to use
the built in heap debugging provided by Microsoft. It's not as feature rich as
duma, but for complex projects were duma is causing issues it will work with less
hassle (it sits in the heap manager itself).
You can control it using the global flags (gflags) utility that comes with windbg.
You can enable it by saying: gflags.exe /p /full /enable MyProgram.exe
And do unaligned by saying: gflags.exe /p /full /unaligned /enable MyProgram.exe
gflags will set specific registry keys to enable the pageheap debugging on the
executable. You can disable it using the "/disable" flag.
See http://support.microsoft.com/kb/286470
MPATROL
The mpatrol library is a powerful debugging tool that attempts to diagnose
run-time errors that are caused by the wrong use of dynamically allocated
memory. It acts as a malloc() debugger for debugging dynamic memory
allocations, although it can also trace and profile calls to malloc()
and free() too.
See http://www.cbmamiga.demon.co.uk/mpatrol/
Purify
does a much more thorough job than DUMA, and does not have the huge memory
overhead.
LibSafe
protects Critical Elements of Stack.
See http://www.research.avayalabs.com/
DieHard
helps buggy programs run correctly and protects them from a range of security
vulnerabilities.
See http://www.diehard-software.org/
electric-fence-win32
another Win32 port of Electric Fence.
See http://code.google.com/p/electric-fence-win32/
FURTHER READING:
Hunting Memory Bugs
http://www.edm2.com/0508/membug.html
An OS/2 Allocator for the STL
http://www.edm2.com/0508/stl.html
Wikipedia
http://en.wikipedia.org/wiki/Memory_debugger
CONTACTING THE AUTHOR:
Hayati Ayguen <h_ayguen@web.de>
Michael Eddington <meddington@gmail.com>
http://duma.sf.net
FILES IN PACKAGE:
SubDirectories:
---------------
win32-vide/* project files for VIDE 1.24 (see http://www.objectcentral.com)
using the Borland C++ Builder 5.5 compiler
(FreeCommandLineTools, see http://www.borland.com)
win32-devcpp/* project files for Dev-C++ 4.9.6 (see http://www.bloodshed.net)
using the gcc compiler (see http://gcc.gnu.org)
win32-msvc/* projects files for Microsoft Visual C++ 6.0 IDE/compiler
(see http://www.microsoft.com)
debian/* don't know; maybe some files for the Debian Linux distribution?
Projects:
---------
dumalib DUMA library. this library should be linked with YOUR program
dumatest first small test program
tstheap second small test program
Files:
------
COPYING-* License files; reade carefully!
README this text file
CHANGES text file listing done CHANGES
duma.h belongs to dumalib
this header file should be included from within YOUR C source
dumapp.h belongs to dumalib
this header file should be included from within YOUR C++ source
duma.c belongs to dumalib
contains malloc/free/.. functions
dumapp.cpp belongs to dumalib
contains C++ new/delete/.. functions redirecting them
to ANSI C malloc/free
page.c belongs to dumalib
library internal source file: contains paging functions
print.c belongs to dumalib; library internal source file: contains
printing/aborting functions
dumatest.c belongs to dumatest
small test program; checks wether dumalib's paging does its job
should work without any errors
tstheap.c belongs to tstheap
small test program; checks wether dumalib's heap does its job
should report many memory leaks after execution.
Makefile Makefile for UNIX/Linux/..
duma.3 source for UNIX man page
duma.sh script for UNIX/Linux to start other programs using the
LD_PRELOAD mechanism
LICENSE:
Copyright (C) 2006 Michael Eddington <meddington@gmail.com>
Copyright (C) 2002-2008 Hayati Ayguen <h_ayguen@web.de>, Procitec GmbH
Copyright (C) 1987-1999 Bruce Perens <bruce@perens.com>
License: GNU GPL (GNU General Public License, see COPYING-GPL) for all files except dumapp.h
License: GNU LGPL (GNU Lesser General Public License, see COPYING-GPL) for dumapp.h
--- GPL --
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
--- LGPL --
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

2605
third_party/duma/duma.c vendored Normal file

File diff suppressed because it is too large Load diff

357
third_party/duma/duma.h vendored Normal file
View file

@ -0,0 +1,357 @@
/*
* DUMA - Red-Zone memory allocator.
* Copyright (C) 2006 Michael Eddington <meddington@gmail.com>
* Copyright (C) 2002-2005 Hayati Ayguen <h_ayguen@web.de>, Procitec GmbH
* Copyright (C) 1987-1999 Bruce Perens <bruce@perens.com>
* License: GNU GPL (GNU General Public License, see COPYING-GPL)
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
* FILE CONTENTS:
* header file for inclusion from YOUR application code
*/
/* explicitly no "#ifndef _DUMA_H_" to allow mutliple inclusions
* within single source file with inclusion of noduma.h in between
*/
#include <stdlib.h>
/*
* #include <stdlib.h>
*
* You must include <stdlib.h> before including <duma.h> !
*
*/
/* for enabling inclusion of duma.h after inclusion of efencint.h */
/* remove previous definitions */
#define SKIP_DUMA_NO_CXX
#include "noduma.h"
#undef SKIP_DUMA_NO_CXX
#include "duma_config.h"
#ifdef __cplusplus
#define DUMA_EXTERN_C extern "C"
#else
#define DUMA_EXTERN_C extern
#endif
#define _STRING_H 1
extern int strcmp(const char *s1, const char *s2);
extern int strncmp(const char *s1, const char *s2, size_t n);
extern size_t strlen(const char *s);
//extern char *strdup(const char *s);
#ifdef DUMA_NO_DUMA
/* enable these macros even in release code, but do nothing */
#define DUMA_newFrame() do { } while(0)
#define DUMA_delFrame() do { } while(0)
#define DUMA_SET_ALIGNMENT(V) do { } while(0)
#define DUMA_SET_PROTECT_BELOW(V) do { } while(0)
#define DUMA_SET_FILL(V) do { } while(0)
#define DUMA_ASSERT(EXPR) do { } while(0)
#define DUMA_CHECK(BASEADR) do { } while(0)
#define DUMA_CHECKALL() do { } while(0)
#define CA_DECLARE(NAME,SIZE) do { } while(0)
#define CA_DEFINE(TYPE,NAME,SIZE) TYPE NAME[SIZE]
#define CA_REF(NAME,INDEX) NAME[INDEX]
#else /* ifndef DUMA_NO_DUMA */
#ifndef DUMA_EXTERNS_DECLARED
#define DUMA_EXTERNS_DECLARED
/* global DUMA variables */
DUMA_EXTERN_C int DUMA_OUTPUT_DEBUG;
DUMA_EXTERN_C int DUMA_OUTPUT_STDOUT;
DUMA_EXTERN_C int DUMA_OUTPUT_STDERR;
DUMA_EXTERN_C char* DUMA_OUTPUT_FILE;
DUMA_EXTERN_C int DUMA_OUTPUT_STACKTRACE;
#endif /* DUMA_EXTERNS_DECLARED */
/* set Maximum Delete Depth (depth of recursive destructor calls) */
#ifndef DUMA_MAX_DEL_DEPTH
#define DUMA_MAX_DEL_DEPTH 256
#endif
#ifndef DUMA_TLSVARTYPE_DEFINED
#define DUMA_TLSVARTYPE_DEFINED
/* TODO following variables should exist per thread ("thread-local") */
typedef struct
{
/*
* ALIGNMENT is a global variable used to control the default alignment
* of buffers returned by malloc(), calloc(), and realloc(). It is all-caps
* so that its name matches the name of the environment variable that is used
* to set it. This gives the programmer one less name to remember.
*/
int ALIGNMENT;
/*
* PROTECT_BELOW is used to modify the behavior of the allocator. When
* its value is non-zero, the allocator will place an inaccessable page
* immediately _before_ the malloc buffer in the address space, instead
* of _after_ it. Use this to detect malloc buffer under-runs, rather than
* over-runs. It won't detect both at the same time, so you should test your
* software twice, once with this value clear, and once with it set.
*/
int PROTECT_BELOW;
/*
* FILL is set to 0-255 if DUMA should fill all new allocated
* memory with the specified value. Set to -1 when DUMA should not
* initialise allocated memory.
* default is set to initialise with 255, cause many programs rely on
* initialisation to 0!
*/
int FILL;
#if !defined(DUMA_NO_CPP_SUPPORT) && !defined(DUMA_NO_LEAKDETECTION)
int Magic;
int DelPtr;
const char * DelFile[DUMA_MAX_DEL_DEPTH];
int DelLine[DUMA_MAX_DEL_DEPTH];
#endif
} DUMA_TLSVARS_T;
#endif
#ifndef DUMA_GLOBALS_DEFINED
#define DUMA_GLOBALS_DEFINED
typedef struct
{
/* Protection Space A */
char acSpaceA[2 * DUMA_PAGE_SIZE];
/* Variable: _duma_allocList
*
* _DUMA_allocList points to the array of slot structures used to manage the
* malloc arena.
*/
struct _DUMA_Slot * allocList;
/* Variable: _duma_null_addr
*
* _duma_null_addr is the address malloc() or C++ operator new returns, when size is 0
* two pages get reserved and protected
*/
void * null_addr;
/* Variable */
DUMA_TLSVARS_T TLS;
/* Protection Space B */
char acSpaceB[2 * DUMA_PAGE_SIZE];
} DUMA_GLOBALVARS_T;
DUMA_EXTERN_C DUMA_GLOBALVARS_T _duma_g;
#endif /* DUMA_GLOBALS_DEFINED */
#define GET_DUMA_TLSVARS() (&_duma_g.TLS)
#ifndef DUMA_SET_ALIGNMENT
#define DUMA_SET_ALIGNMENT(V) GET_DUMA_TLSVARS()->ALIGNMENT = (V)
#endif
#ifndef DUMA_SET_PROTECT_BELOW
#define DUMA_SET_PROTECT_BELOW(V) GET_DUMA_TLSVARS()->PROTECT_BELOW = (V)
#endif
#ifndef DUMA_SET_FILL
#define DUMA_SET_FILL(V) GET_DUMA_TLSVARS()->FILL = (V)
#endif
#ifndef DUMA_ENUMS_DECLARED
#define DUMA_ENUMS_DECLARED
/* allocator defines the type of calling allocator/deallocator function */
enum _DUMA_Allocator
{
EFA_INT_ALLOC
, EFA_INT_DEALLOC
, EFA_MALLOC
, EFA_CALLOC
, EFA_FREE
, EFA_MEMALIGN
, EFA_POSIX_MEMALIGN
, EFA_REALLOC
, EFA_VALLOC
, EFA_STRDUP
, EFA_NEW_ELEM
, EFA_DEL_ELEM
, EFA_NEW_ARRAY
, EFA_DEL_ARRAY
/* use following enums when calling _duma_allocate()/_duma_deallocate()
* from user defined member operators
*/
, EFA_MEMBER_NEW_ELEM
, EFA_MEMBER_DEL_ELEM
, EFA_MEMBER_NEW_ARRAY
, EFA_MEMBER_DEL_ARRAY
};
enum _DUMA_FailReturn
{
DUMA_FAIL_NULL
, DUMA_FAIL_ENV
};
#endif /* DUMA_ENUMS_DECLARED */
#ifndef DUMA_FUNCTIONS_DECLARED
#define DUMA_FUNCTIONS_DECLARED
DUMA_EXTERN_C void _duma_init(void);
DUMA_EXTERN_C void _duma_assert(const char * exprstr, const char * filename, int lineno);
DUMA_EXTERN_C void duma_check(void * address);
DUMA_EXTERN_C void duma_checkAll();
DUMA_EXTERN_C void * duma_alloc_return( void * address );
#ifdef DUMA_EXPLICIT_INIT
DUMA_EXTERN_C void duma_init(void);
#endif
#ifndef DUMA_NO_LEAKDETECTION
DUMA_EXTERN_C void * _duma_allocate(size_t alignment, size_t userSize, int protectBelow, int fillByte, int protectAllocList, enum _DUMA_Allocator allocator, enum _DUMA_FailReturn fail, const char * filename, int lineno);
DUMA_EXTERN_C void _duma_deallocate(void * baseAdr, int protectAllocList, enum _DUMA_Allocator allocator, const char * filename, int lineno);
DUMA_EXTERN_C void * _duma_malloc(size_t size, const char * filename, int lineno);
DUMA_EXTERN_C void * _duma_calloc(size_t elemCount, size_t elemSize, const char * filename, int lineno);
DUMA_EXTERN_C void _duma_free(void * baseAdr, const char * filename, int lineno);
DUMA_EXTERN_C void * _duma_memalign(size_t alignment, size_t userSize, const char * filename, int lineno);
DUMA_EXTERN_C int _duma_posix_memalign(void **memptr, size_t alignment, size_t userSize, const char * filename, int lineno);
DUMA_EXTERN_C void * _duma_realloc(void * baseAdr, size_t newSize, const char * filename, int lineno);
DUMA_EXTERN_C void * _duma_valloc(size_t size, const char * filename, int lineno);
DUMA_EXTERN_C char * _duma_strdup(const char *str, const char * filename, int lineno);
DUMA_EXTERN_C void * _duma_memcpy(void *dest, const void *src, size_t size, const char * filename, int lineno);
DUMA_EXTERN_C char * _duma_strcpy(char *dest, const char *src, const char * filename, int lineno);
DUMA_EXTERN_C char * _duma_strncpy(char *dest, const char *src, size_t size, const char * filename, int lineno);
DUMA_EXTERN_C char * _duma_strcat(char *dest, const char *src, const char * filename, int lineno);
DUMA_EXTERN_C char * _duma_strncat(char *dest, const char *src, size_t size, const char * filename, int lineno);
DUMA_EXTERN_C void DUMA_newFrame(void);
DUMA_EXTERN_C void DUMA_delFrame(void);
#else /* DUMA_NO_LEAKDETECTION */
DUMA_EXTERN_C void * _duma_allocate(size_t alignment, size_t userSize, int protectBelow, int fillByte, int protectAllocList, enum _DUMA_Allocator allocator, enum _DUMA_FailReturn fail);
DUMA_EXTERN_C void _duma_deallocate(void * baseAdr, int protectAllocList, enum _DUMA_Allocator allocator);
DUMA_EXTERN_C void * _duma_malloc(size_t size);
DUMA_EXTERN_C void * _duma_calloc(size_t elemCount, size_t elemSize);
DUMA_EXTERN_C void _duma_free(void * baseAdr);
DUMA_EXTERN_C void * _duma_memalign(size_t alignment, size_t userSize);
DUMA_EXTERN_C int _duma_posix_memalign(void **memptr, size_t alignment, size_t userSize);
DUMA_EXTERN_C void * _duma_realloc(void * baseAdr, size_t newSize);
DUMA_EXTERN_C void * _duma_valloc(size_t size);
DUMA_EXTERN_C char * _duma_strdup(const char *str);
DUMA_EXTERN_C void * _duma_memcpy(void *dest, const void *src, size_t size);
DUMA_EXTERN_C char * _duma_strcpy(char *dest, const char *src);
DUMA_EXTERN_C char * _duma_strncpy(char *dest, const char *src, size_t size);
DUMA_EXTERN_C char * _duma_strcat(char *dest, const char *src);
DUMA_EXTERN_C char * _duma_strncat(char *dest, const char *src, size_t size);
#endif /* DUMA_NO_LEAKDETECTION */
#endif /* DUMA_FUNCTIONS_DECLARED */
#ifndef DUMA_SKIP_SETUP
#ifndef DUMA_NO_LEAKDETECTION
#define malloc(SIZE) _duma_malloc(SIZE, __FILE__, __LINE__)
#define calloc(ELEMCOUNT, ELEMSIZE) _duma_calloc(ELEMCOUNT, ELEMSIZE, __FILE__, __LINE__)
#define free(BASEADR) _duma_free(BASEADR, __FILE__, __LINE__)
#define memalign(ALIGNMENT, SIZE) _duma_memalign(ALIGNMENT, SIZE, __FILE__, __LINE__)
#define posix_memalign(MEMPTR, ALIGNMENT, SIZE) _duma_posix_memalign(MEMPTR, ALIGNMENT, SIZE, __FILE__, __LINE__)
#define realloc(BASEADR, NEWSIZE) _duma_realloc(BASEADR, NEWSIZE, __FILE__, __LINE__)
#define valloc(SIZE) _duma_valloc(SIZE, __FILE__, __LINE__)
#define strdup(STR) _duma_strdup(STR, __FILE__, __LINE__)
#define memcpy(DEST, SRC, SIZE) _duma_memcpy(DEST, SRC, SIZE, __FILE__, __LINE__)
#define strcpy(DEST, SRC) _duma_strcpy(DEST, SRC, __FILE__, __LINE__)
#define strncpy(DEST, SRC, SIZE) _duma_strncpy(DEST, SRC, SIZE, __FILE__, __LINE__)
#define strcat(DEST, SRC) _duma_strcat(DEST, SRC, __FILE__, __LINE__)
#define strncat(DEST, SRC, SIZE) _duma_strncat(DEST, SRC, SIZE, __FILE__, __LINE__)
#else /* DUMA_NO_LEAKDETECTION */
#define DUMA_newFrame() do { } while(0)
#define DUMA_delFrame() do { } while(0)
#endif /* DUMA_NO_LEAKDETECTION */
#endif // DUMA_SKIP_SETUP
#ifndef DUMA_ASSERT
#define DUMA_ASSERT(EXPR) ( (EXPR) || ( _duma_assert(#EXPR, __FILE__, __LINE__), 0 ) )
#endif
#ifndef DUMA_CHECK
#define DUMA_CHECK(BASEADR) duma_check(BASEADR)
#endif
#ifndef DUMA_CHECKALL
#define DUMA_CHECKALL() duma_checkAll()
#endif
/*
* protection of functions return address
*/
#ifdef __GNUC__
#define DUMA_FN_PROT_START const void * DUMA_RET_ADDR = __builtin_return_address(0); {
#define DUMA_FN_PROT_END } DUMA_ASSERT( __builtin_return_address(0) == DUMA_RET_ADDR );
#define DUMA_FN_PROT_RET(EXPR) do { DUMA_ASSERT( __builtin_return_address(0) == DUMA_RET_ADDR ); return( EXPR ); } while (0)
#define DUMA_FN_PROT_RET_VOID() do { DUMA_ASSERT( __builtin_return_address(0) == DUMA_RET_ADDR ); return; } while (0)
#else
#define DUMA_FN_PROT_START int aiDUMA_PROT[ 4 ] = { 'E', 'F', 'P', 'R' }; {
#define DUMA_FN_PROT_END } DUMA_ASSERT( 'E'==aiDUMA_PROT[0] && 'F'==aiDUMA_PROT[1] && 'P'==aiDUMA_PROT[2] && 'R'==aiDUMA_PROT[3] );
#define DUMA_FN_PROT_RET(EXPR) do { DUMA_ASSERT( 'E'==aiDUMA_PROT[0] && 'F'==aiDUMA_PROT[1] && 'P'==aiDUMA_PROT[2] && 'R'==aiDUMA_PROT[3] ); return( EXPR ); } while (0)
#define DUMA_FN_PROT_RET_VOID() do { DUMA_ASSERT( 'E'==aiDUMA_PROT[0] && 'F'==aiDUMA_PROT[1] && 'P'==aiDUMA_PROT[2] && 'R'==aiDUMA_PROT[3] ); return; } while (0)
#endif
/* declaration of an already defined array to enable checking at every reference
* when using CA_REF()
*/
#define CA_DECLARE(NAME,SIZE) \
const unsigned long NAME ## _checkedsize = (SIZE); \
unsigned long NAME ## _checkedidx
/* definition of a checked array adds definitions for its size and an extra temporary.
* every array gets its own temporary to avoid problems with threading
* a global temporary would have.
*/
#define CA_DEFINE(TYPE,NAME,SIZE) TYPE NAME[SIZE]; CA_DECLARE(NAME,SIZE)
/* every access to a checked array is preceded an assert() on the index;
* the index parameter is stored to a temporary to avoid double execution of index,
* when index contains f.e. a "++".
*/
#define CA_REF(NAME,INDEX) \
NAME[ DUMA_ASSERT( (NAME ## _checkedidx = (INDEX)) < NAME ## _checkedsize ), NAME ## _checkedidx ]
#endif /* end ifdef DUMA_NO_DUMA */

216
third_party/duma/duma_config.h vendored Normal file
View file

@ -0,0 +1,216 @@
/*
* WARNING: DO NOT CHANGE THIS FILE!
* This file is automatically generated from createconf
* under Linux the Apr 30 2015
*/
#ifndef _DUMA_CONFIG_H_
#define _DUMA_CONFIG_H_
/*
* Configuration of DUMA:
*/
#ifdef DUMA_SO_LIBRARY
#ifdef DUMA_NO_GLOBAL_MALLOC_FREE
#undef DUMA_NO_GLOBAL_MALLOC_FREE
#endif
#ifdef DUMA_EXPLICIT_INIT
#undef DUMA_EXPLICIT_INIT
#endif
#ifdef DUMA_NO_THREAD_SAFETY
#undef DUMA_NO_THREAD_SAFETY
#endif
#ifdef DUMA_SEMAPHORES
#undef DUMA_SEMAPHORES
#endif
#ifdef DUMA_NO_CPP_SUPPORT
#undef DUMA_NO_CPP_SUPPORT
#endif
#ifndef DUMA_NO_LEAKDETECTION
#define DUMA_NO_LEAKDETECTION
#endif
#ifdef DUMA_PREFER_ATEXIT
#undef DUMA_PREFER_ATEXIT
#endif
#ifdef DUMA_PREFER_GETENV
#undef DUMA_PREFER_GETENV
#endif
#ifdef DUMA_OLD_NEW_MACRO
#undef DUMA_OLD_NEW_MACRO
#endif
#ifdef DUMA_OLD_DEL_MACRO
#undef DUMA_OLD_DEL_MACRO
#endif
#ifdef DUMA_NO_STRERROR
#undef DUMA_NO_STRERROR
#endif
#ifdef DUMA_NO_HANG_MSG
#undef DUMA_NO_HANG_MSG
#endif
#elif defined(DUMA_DLL_LIBRARY)
#define DUMA_SKIP_SETUP 1
#define DUMA_NO_GLOBAL_MALLOC_FREE 1
#define DUMA_EXPLICIT_INIT 1
#ifdef DUMA_NO_THREAD_SAFETY
#undef DUMA_NO_THREAD_SAFETY
#endif
#ifdef DUMA_NO_CPP_SUPPORT
#undef DUMA_NO_CPP_SUPPORT
#endif
#ifndef DUMA_NO_LEAKDETECTION
#define DUMA_NO_LEAKDETECTION
#endif
#ifdef DUMA_PREFER_ATEXIT
#undef DUMA_PREFER_ATEXIT
#endif
#ifdef DUMA_PREFER_GETENV
#undef DUMA_PREFER_GETENV
#endif
#ifdef DUMA_OLD_NEW_MACRO
#undef DUMA_OLD_NEW_MACRO
#endif
#ifdef DUMA_OLD_DEL_MACRO
#undef DUMA_OLD_DEL_MACRO
#endif
#ifdef DUMA_NO_HANG_MSG
#undef DUMA_NO_HANG_MSG
#endif
#elif defined(DUMA_DETOURS)
#define DUMA_SKIP_SETUP 1
#define DUMA_NO_GLOBAL_MALLOC_FREE 1
#define DUMA_EXPLICIT_INIT 1
#ifdef DUMA_NO_THREAD_SAFETY
#undef DUMA_NO_THREAD_SAFETY
#endif
#ifdef DUMA_NO_CPP_SUPPORT
#undef DUMA_NO_CPP_SUPPORT
#endif
#ifndef DUMA_NO_LEAKDETECTION
#define DUMA_NO_LEAKDETECTION
#endif
#ifdef DUMA_PREFER_ATEXIT
#undef DUMA_PREFER_ATEXIT
#endif
#ifdef DUMA_PREFER_GETENV
#undef DUMA_PREFER_GETENV
#endif
#ifdef DUMA_OLD_NEW_MACRO
#undef DUMA_OLD_NEW_MACRO
#endif
#ifdef DUMA_OLD_DEL_MACRO
#undef DUMA_OLD_DEL_MACRO
#endif
#ifdef DUMA_NO_HANG_MSG
#undef DUMA_NO_HANG_MSG
#endif
#else
#ifdef DUMA_NO_GLOBAL_MALLOC_FREE
#undef DUMA_NO_GLOBAL_MALLOC_FREE
#endif
#ifdef DUMA_EXPLICIT_INIT
#undef DUMA_EXPLICIT_INIT
#endif
#ifdef DUMA_NO_THREAD_SAFETY
#undef DUMA_NO_THREAD_SAFETY
#endif
#ifdef DUMA_NO_CPP_SUPPORT
#undef DUMA_NO_CPP_SUPPORT
#endif
#ifdef DUMA_NO_LEAKDETECTION
#undef DUMA_NO_LEAKDETECTION
#endif
#ifdef DUMA_PREFER_ATEXIT
#undef DUMA_PREFER_ATEXIT
#endif
#ifdef DUMA_PREFER_GETENV
#undef DUMA_PREFER_GETENV
#endif
#ifdef DUMA_OLD_NEW_MACRO
#undef DUMA_OLD_NEW_MACRO
#endif
#ifdef DUMA_OLD_DEL_MACRO
#undef DUMA_OLD_DEL_MACRO
#endif
#ifdef DUMA_NO_STRERROR
#undef DUMA_NO_STRERROR
#endif
#ifdef DUMA_NO_HANG_MSG
#undef DUMA_NO_HANG_MSG
#endif
#endif
/*
* Number of bytes per virtual-memory page, as returned by Page_Size().
*/
#define DUMA_PAGE_SIZE 4096
/*
* Minimum required alignment by CPU.
*/
#define DUMA_MIN_ALIGNMENT 1
/*
* Build environment supports the '__attribute ((constructor))'?
*/
#define DUMA_GNU_INIT_ATTR 1
/*
* An integer type with same size as 'void *'
*/
typedef unsigned long int DUMA_ADDR;
/*
* An integer type with same size as 'size_t'
*/
typedef unsigned long int DUMA_SIZE;
/*
* Default behaviour on malloc(0).
*/
#define DUMA_DEFAULT_MALLOC_0_STRATEGY 3
#endif /* _DUMA_CONFIG_H_ */

308
third_party/duma/duma_hlp.h vendored Normal file
View file

@ -0,0 +1,308 @@
/*
* DUMA - Red-Zone memory allocator.
* Copyright (C) 2002-2005 Hayati Ayguen <h_ayguen@web.de>, Procitec GmbH
* License: GNU LGPL (GNU Lesser General Public License, see COPYING-GPL)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* FILE CONTENTS:
* internal implementation file
* contains helper functions for DUMA
*/
/* Function: reduceProtectedMemory
*
* delete reductionSizekB amount of memory, which has already
* been freed but got protected
* return != 0 when more memory reducable
*/
static int
reduceProtectedMemory( size_t reductionSizekB )
{
struct _DUMA_Slot * slot = _duma_g.allocList;
size_t count = _duma_s.slotCount;
size_t alreadyReducekB = 0;
#ifndef WIN32
/* Windows VirtualFree(,,MEM_RELEASE) can only free whole allocations. not parts */
size_t delSize, newSize;
/* 1- try reducing memory to just keep page(s) with userAddress */
for ( ; count > 0 && alreadyReducekB < reductionSizekB; --count, ++slot )
if ( DUMAST_ALL_PROTECTED == slot->state )
{
/* free memory above userAddr; keep userAddr protected */
newSize = (char*)slot->userAddress - (char*)slot->internalAddress;
newSize = (newSize + DUMA_PAGE_SIZE) & ~(DUMA_PAGE_SIZE -1);
delSize = slot->internalSize - newSize;
Page_Delete( (char*)slot->internalAddress + newSize, delSize );
alreadyReducekB += (delSize+1023) >>10;
slot->state = DUMAST_BEGIN_PROTECTED;
/* but keep the slot and userAddr */
slot->internalSize = newSize;
if ( alreadyReducekB >= reductionSizekB )
{
_duma_s.sumProtectedMem -= alreadyReducekB;
_duma_s.sumAllocatedMem -= alreadyReducekB;
return 1;
}
}
#endif
/* 2- deallocate all page(s) with userAddress, empty whole slot */
slot = _duma_g.allocList;
count = _duma_s.slotCount;
for ( ; count > 0 && alreadyReducekB < reductionSizekB; --count, ++slot )
if ( DUMAST_BEGIN_PROTECTED == slot->state
#if defined(WIN32)
|| DUMAST_ALL_PROTECTED == slot->state
#endif
)
{
/* free all the memory */
Page_Delete(slot->internalAddress, slot->internalSize);
alreadyReducekB += (slot->internalSize+1023) >>10;
/* free slot and userAddr */
slot->internalAddress = slot->userAddress = 0;
slot->internalSize = slot->userSize = 0;
slot->state = DUMAST_EMPTY;
slot->allocator = EFA_INT_ALLOC;
#ifndef DUMA_NO_LEAKDETECTION
slot->fileSource = DUMAFS_EMPTY;
slot->filename = 0;
slot->lineno = 0;
#endif
if ( alreadyReducekB >= reductionSizekB )
{
_duma_s.sumProtectedMem -= alreadyReducekB;
_duma_s.sumAllocatedMem -= alreadyReducekB;
return 1;
}
}
return 0;
}
/* Function: slotForUserAddress
*
* Find the slot structure for a user address.
*/
static struct _DUMA_Slot *
slotForUserAddress(void * address)
{
struct _DUMA_Slot * slot = _duma_g.allocList;
size_t count = _duma_s.slotCount;
for ( ; count > 0; --count, ++slot )
if ( slot->userAddress == address )
return slot;
return 0;
}
/* Function: nearestSlotForUserAddress
*
* Find the nearest slot structure for a user address.
*/
static struct _DUMA_Slot *
nearestSlotForUserAddress(void * userAddress)
{
struct _DUMA_Slot * slot = _duma_g.allocList;
size_t count = _duma_s.slotCount;
for ( ; count > 0; --count, ++slot )
if ( (char*)slot->internalAddress <= (char*)userAddress
&& (char*)userAddress <= (char*)slot->internalAddress + slot->internalSize
)
return slot;
return 0;
}
#if 0
/* next to functions not needed so far .. */
/* Function: slotForInternalAddrNextTo
*
* Find the slot structure for an internal address.
*/
static struct _DUMA_Slot *
slotForInternalAddrNextTo(void * address)
{
struct _DUMA_Slot * slot = _duma_g.allocList;
size_t count = _duma_s.slotCount;
for ( ; count > 0; --count, ++slot )
if ( slot->internalAddress == address )
return slot;
return 0;
}
/* Function: slotForInternalAddrPrevTo
*
* Given the internal address of a buffer, find the buffer immediately
* before that buffer in the address space. This is used by free() to
* coalesce two free buffers into one.
*/
static struct _DUMA_Slot *
slotForInternalAddrPrevTo(void * address)
{
struct _DUMA_Slot * slot = _duma_g.allocList;
size_t count = _duma_s.slotCount;
for ( ; count > 0; --count, ++slot )
if ( (char*)slot->internalAddress + slot->internalSize == address )
return slot;
return 0;
}
#endif
/* Function: _duma_init_slack
*
* Initialise the no mans land, for a given slot
*/
static
void _duma_init_slack( struct _DUMA_Slot * slot )
{
char * accBegAddr, * accEndAddr;
char * tmpBegAddr, * tmpEndAddr;
#ifdef DUMA_EXPLICIT_INIT
slot->slackfill = _duma_s.SLACKFILL;
#endif
/* nothing to do for zero userSize */
if ( !slot->userSize )
return;
/* calculate accessible non-protectable address area */
if ( (char*)slot->protAddress < (char*)slot->userAddress )
{
/* DUMA_PROTECT_BELOW was 1 when allocating this piece of memory */
accBegAddr = (char*)slot->userAddress;
accEndAddr = (char*)slot->internalAddress + slot->internalSize;
}
else
{
/* DUMA_PROTECT_BELOW was 0 when allocating this piece of memory */
accBegAddr = (char*)slot->internalAddress;
accEndAddr = (char*)slot->protAddress;
}
tmpBegAddr = accBegAddr;
tmpEndAddr = (char*)slot->userAddress;
while (tmpBegAddr < tmpEndAddr)
*tmpBegAddr++ = (char)_duma_s.SLACKFILL;
tmpBegAddr = (char*)slot->userAddress + slot->userSize;
tmpEndAddr = accEndAddr;
while (tmpBegAddr < tmpEndAddr)
*tmpBegAddr++ = (char)_duma_s.SLACKFILL;
}
/* Function: _duma_check_slack
*
* Checks the integrity of no mans land, for a given slot
*/
static
void _duma_check_slack( struct _DUMA_Slot * slot )
{
char * accBegAddr, * accEndAddr;
char * tmpBegAddr, * tmpEndAddr;
char slackfill;
#ifdef DUMA_EXPLICIT_INIT
slackfill = (char)slot->slackfill;
#else
slackfill = (char)_duma_s.SLACKFILL;
#endif
/* nothing to do for zero userSize */
if ( !slot->userSize )
return;
/* calculate accessible non-protectable address area */
if ( (char*)slot->protAddress < (char*)slot->userAddress )
{
/* DUMA_PROTECT_BELOW was 1 when allocating this piece of memory */
accBegAddr = (char*)slot->userAddress;
accEndAddr = (char*)slot->internalAddress + slot->internalSize;
}
else
{
/* DUMA_PROTECT_BELOW was 0 when allocating this piece of memory */
accBegAddr = (char*)slot->internalAddress;
accEndAddr = (char*)slot->protAddress;
}
tmpBegAddr = accBegAddr;
tmpEndAddr = (char*)slot->userAddress;
while (tmpBegAddr < tmpEndAddr)
{
if ( (char)slackfill != *tmpBegAddr++ )
{
#ifndef DUMA_NO_LEAKDETECTION
DUMA_Abort("ptr=%a: detected overwrite of ptrs no mans land below userSpace, size=%d alloced from %s(%i)",
(DUMA_ADDR)slot->userAddress, (DUMA_SIZE)slot->userSize, slot->filename, slot->lineno);
#else
DUMA_Abort("ptr=%a: detected overwrite of ptrs no mans land below userSpace", (DUMA_ADDR)slot->userAddress);
#endif
}
}
tmpBegAddr = (char*)slot->userAddress + slot->userSize;
tmpEndAddr = accEndAddr;
while (tmpBegAddr < tmpEndAddr)
{
if ( (char)slackfill != *tmpBegAddr++ )
{
#ifndef DUMA_NO_LEAKDETECTION
DUMA_Abort("detected overwrite of no mans land above userSpace: ptr=%a, size=%d\nalloced from %s(%i)",
(DUMA_ADDR)slot->userAddress, (DUMA_SIZE)slot->userSize, slot->filename, slot->lineno);
#else
DUMA_Abort("detected overwrite of no mans land above userSpace: ptr=%a", (DUMA_ADDR)slot->userAddress);
#endif
}
}
}
/* Function: _duma_check_all_slacks
*
* Checks the integrity of all no mans land
*/
static void
_duma_check_all_slacks( void )
{
struct _DUMA_Slot * slot = _duma_g.allocList;
size_t count = _duma_s.slotCount;
for ( ; count > 0; --count, ++slot )
{
/* CHECK INTEGRITY OF NO MANS LAND */
if ( DUMAST_IN_USE == slot->state && slot->userSize )
_duma_check_slack( slot );
}
}
// end

57
third_party/duma/duma_sem.h vendored Normal file
View file

@ -0,0 +1,57 @@
/*
* DUMA - Red-Zone memory allocator.
* Copyright (C) 2002-2005 Hayati Ayguen <h_ayguen@web.de>, Procitec GmbH
* License: GNU LGPL (GNU Lesser General Public License, see COPYING-GPL)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* FILE CONTENTS:
* internal header file
*/
#ifndef DUMA_SEM_INC_H
#define DUMA_SEM_INC_H
#ifndef DUMA_NO_THREAD_SAFETY
#ifdef __cplusplus
extern "C" {
#endif
void DUMA_init_sem(void);
void DUMA_get_sem(void);
int DUMA_rel_sem(int retval);
#ifdef __cplusplus
} /* extern "C" */
#endif
#define DUMA_INIT_SEMAPHORE() DUMA_init_sem()
#define DUMA_GET_SEMAPHORE() DUMA_get_sem()
#define DUMA_RELEASE_SEMAPHORE(x) DUMA_rel_sem(x)
#else /* DUMA_NO_THREAD_SAFETY */
#define DUMA_INIT_SEMAPHORE() do { } while (0)
#define DUMA_GET_SEMAPHORE() do { } while (0)
#define DUMA_RELEASE_SEMAPHORE(x) do { } while (0)
#endif /* DUMA_NO_THREAD_SAFETY */
#endif /* DUMA_SEM_INC_H */

206
third_party/duma/noduma.h vendored Normal file
View file

@ -0,0 +1,206 @@
/*
* DUMA - Red-Zone memory allocator.
* Copyright (C) 2002-2008 Hayati Ayguen <h_ayguen@web.de>, Procitec GmbH
* Copyright (C) 1987-1999 Bruce Perens <bruce@perens.com>
* License: GNU GPL (GNU General Public License, see COPYING-GPL)
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
* FILE CONTENTS:
* header file for inclusion from YOUR application code.
* Include this header before including foreign includes
* from inside your own headers files.
*/
/* remove previous DUMA definitions */
#ifdef DUMA_newFrame
#undef DUMA_newFrame
#endif
#ifdef DUMA_delFrame
#undef DUMA_delFrame
#endif
#ifdef DUMA_SET_ALIGNMENT
#undef DUMA_SET_ALIGNMENT
#endif
#ifdef DUMA_SET_PROTECT_BELOW
#undef DUMA_SET_PROTECT_BELOW
#endif
#ifdef DUMA_SET_FILL
#undef DUMA_SET_FILL
#endif
/* remove previous wrappers to standard C functions */
#ifdef malloc
#undef malloc
#endif
#ifdef calloc
#undef calloc
#endif
#ifdef free
#undef free
#endif
#ifdef memalign
#undef memalign
#endif
#ifdef posix_memalign
#undef posix_memalign
#endif
#ifdef realloc
#undef realloc
#endif
#ifdef valloc
#undef valloc
#endif
#ifdef strdup
#undef strdup
#endif
#ifdef memcpy
#undef memcpy
#endif
#ifdef strcpy
#undef strcpy
#endif
#ifdef strncpy
#undef strncpy
#endif
#ifdef strcat
#undef strcat
#endif
#ifdef strncat
#undef strncat
#endif
#ifndef SKIP_DUMA_NO_CXX
/* remove previous wrappers to standard C++ functions / operators */
#ifdef new
#undef new
#endif
#ifdef delete
#undef delete
#endif
#ifdef new_NOTHROW
#undef new_NOTHROW
#endif
/* remove previous DUMA C++ definitions */
#ifdef NEW_ELEM
#undef NEW_ELEM
#endif
#ifdef NEW_ARRAY
#undef NEW_ARRAY
#endif
#ifdef NEW_ELEM_NOTHROW
#undef NEW_ELEM_NOTHROW
#endif
#ifdef NEW_ARRAY_NOTHROW
#undef NEW_ARRAY_NOTHROW
#endif
#ifdef DEL_ELEM
#undef DEL_ELEM
#endif
#ifdef DEL_ARRAY
#undef DEL_ARRAY
#endif
#ifdef DEL_ELEM_NOTHROW
#undef DEL_ELEM_NOTHROW
#endif
#ifdef DEL_ARRAY_NOTHROW
#undef DEL_ARRAY_NOTHROW
#endif
#endif /* SKIP_DUMA_NO_CXX */
/* remove definitions for protection of functions return address */
#ifdef DUMA_FN_PROT_START
#undef DUMA_FN_PROT_START
#endif
#ifdef DUMA_FN_PROT_END
#undef DUMA_FN_PROT_END
#endif
#ifdef DUMA_FN_PROT_RET
#undef DUMA_FN_PROT_RET
#endif
#ifdef DUMA_FN_PROT_RET_VOID
#undef DUMA_FN_PROT_RET_VOID
#endif
/* remove (C)hecked (A)rray definitions */
#ifdef CA_DECLARE
#undef CA_DECLARE
#endif
#ifdef CA_DEFINE
#undef CA_DEFINE
#endif
#ifdef CA_REF
#undef CA_REF
#endif
/* Following defines are kept:
*
* DUMA_ASSERT
* DUMA_CHECK
* DUMA_CHECKALL
* DUMA_CDECL
* DUMA_SIZE_T
* DUMA_MAX_DEL_DEPTH
*
*/
/***************/
/* END OF FILE */
/***************/

394
third_party/duma/paging.h vendored Normal file
View file

@ -0,0 +1,394 @@
/* Title: paging.h */
/*
* DUMA - Red-Zone memory allocator.
* Copyright (C) 2006 Michael Eddington <meddington@gmail.com>
* Copyright (C) 2002-2008 Hayati Ayguen <h_ayguen@web.de>, Procitec GmbH
* Copyright (C) 1987-1999 Bruce Perens <bruce@perens.com>
* License: GNU GPL (GNU General Public License, see COPYING-GPL)
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
* FILE CONTENTS:
* internal implementation file
* contains system/platform dependent paging functions
*/
#ifndef DUMA_PAGING_H
#define DUMA_PAGING_H
/*
* Lots of systems are missing the definition of PROT_NONE.
*/
#ifndef PROT_NONE
#define PROT_NONE 0
#endif
/*
* 386 BSD has MAP_ANON instead of MAP_ANONYMOUS.
*/
#if ( !defined(MAP_ANONYMOUS) && defined(MAP_ANON) )
#define MAP_ANONYMOUS MAP_ANON
#endif
/*
* For some reason, I can't find mprotect() in any of the headers on
* IRIX or SunOS 4.1.2
*/
/* extern C_LINKAGE int mprotect(void * addr, size_t len, int prot); */
#if !defined(WIN32)
static caddr_t startAddr = (caddr_t) 0;
#endif
/* Function: stringErrorReport
*
* Get formatted error string and return. For WIN32
* FormatMessage is used, strerror all else.
*/
static const char * stringErrorReport(void)
{
#if defined(WIN32)
DWORD LastError;
LPVOID lpMsgBuf;
LastError = GetLastError();
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS
, NULL
, LastError
, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT) /* Default language */
, (LPTSTR) &lpMsgBuf
, 0
, NULL
);
return (char*)lpMsgBuf; /* "Unknown error.\n"; */
#elif defined(DUMA_NO_STRERROR)
return DUMA_strerror(errno);
#else
return strerror(errno);
#endif
}
/* Function: mprotectFailed
*
* Report that VirtualProtect or mprotect failed and abort
* program execution.
*/
static void mprotectFailed(void)
{
#if defined(WIN32)
DUMA_Abort("VirtualProtect() failed: %s", stringErrorReport());
#else
DUMA_Abort("mprotect() failed: %s.\nCheck README section 'MEMORY USAGE AND EXECUTION SPEED'\n if your (Linux) system may limit the number of different page mappings per process", stringErrorReport());
#endif
}
/* Function: Page_Create
*
* Create memory. Allocates actual memory. Uses
* VirtualAlloc on windows and mmap on unix.
*
* See Also:
* <Page_Delete>
*/
static void *
Page_Create(size_t size, int exitonfail, int printerror)
{
caddr_t allocation;
#if defined(WIN32)
allocation = VirtualAlloc(
NULL /* address of region to reserve or commit */
, (DWORD) size /* size of region */
, (DWORD) MEM_COMMIT /* type of allocation */
, (DWORD) PAGE_READWRITE /* type of access protection */
);
if ( (caddr_t)0 == allocation )
{
if ( exitonfail )
DUMA_Abort("VirtualAlloc(%d) failed: %s", (DUMA_SIZE)size, stringErrorReport());
else if ( printerror )
DUMA_Print("\nDUMA warning: VirtualAlloc(%d) failed: %s", (DUMA_SIZE)size, stringErrorReport());
}
#elif defined(MAP_ANONYMOUS)
/*
* In this version, "startAddr" is a _hint_, not a demand.
* When the memory I map here is contiguous with other
* mappings, the allocator can coalesce the memory from two
* or more mappings into one large contiguous chunk, and thus
* might be able to find a fit that would not otherwise have
* been possible. I could _force_ it to be contiguous by using
* the MMAP_FIXED flag, but I don't want to stomp on memory mappings
* generated by other software, etc.
*/
allocation = (caddr_t) mmap(
startAddr
, (int)size
, PROT_READ|PROT_WRITE
, MAP_PRIVATE|MAP_ANONYMOUS
, -1
, 0
);
#ifndef __hpux
/*
* Set the "address hint" for the next mmap() so that it will abut
* the mapping we just created.
*
* HP/UX 9.01 has a kernel bug that makes mmap() fail sometimes
* when given a non-zero address hint, so we'll leave the hint set
* to zero on that system. HP recently told me this is now fixed.
* Someone please tell me when it is probable to assume that most
* of those systems that were running 9.01 have been upgraded.
*/
startAddr = allocation + size;
#endif
if ( allocation == (caddr_t)-1 )
{
allocation = (caddr_t)0;
if ( exitonfail )
DUMA_Abort("mmap(%d) failed: %s", (DUMA_SIZE)size, stringErrorReport());
else if ( printerror )
DUMA_Print("\nDUMA warning: mmap(%d) failed: %s", (DUMA_SIZE)size, stringErrorReport());
}
#else
static int devZeroFd = -1;
if ( devZeroFd == -1 )
{
devZeroFd = open("/dev/zero", O_RDWR);
if ( devZeroFd < 0 )
DUMA_Abort( "open() on /dev/zero failed: %s", stringErrorReport() );
}
/*
* In this version, "startAddr" is a _hint_, not a demand.
* When the memory I map here is contiguous with other
* mappings, the allocator can coalesce the memory from two
* or more mappings into one large contiguous chunk, and thus
* might be able to find a fit that would not otherwise have
* been possible. I could _force_ it to be contiguous by using
* the MMAP_FIXED flag, but I don't want to stomp on memory mappings
* generated by other software, etc.
*/
allocation = (caddr_t) mmap(
startAddr
, (int)size
, PROT_READ|PROT_WRITE
, MAP_PRIVATE
, devZeroFd
, 0
);
startAddr = allocation + size;
if ( allocation == (caddr_t)-1 )
{
allocation = (caddr_t)0;
if ( exitonfail )
DUMA_Abort("mmap(%d) failed: %s", (DUMA_SIZE)size, stringErrorReport());
else if ( printerror )
DUMA_Print("\nDUMA warning: mmap(%d) failed: %s", (DUMA_SIZE)size, stringErrorReport());
}
#endif
// TESTING
// memset((void*)allocation, 0, startAddr);
return (void *)allocation;
}
/* Function: Page_AllowAccess
*
* Allow memory access to allocated memory.
*
* See Also:
* <Page_DenyAccess>
*/
void Page_AllowAccess(void * address, size_t size)
{
#if defined(WIN32)
SIZE_T OldProtect, retQuery;
MEMORY_BASIC_INFORMATION MemInfo;
size_t tail_size;
BOOL ret;
while (size >0)
{
retQuery = VirtualQuery(address, &MemInfo, sizeof(MemInfo));
if (retQuery < sizeof(MemInfo))
DUMA_Abort("VirtualQuery() failed\n");
tail_size = (size > MemInfo.RegionSize) ? MemInfo.RegionSize : size;
ret = VirtualProtect(
(LPVOID) address /* address of region of committed pages */
, (DWORD) tail_size /* size of the region */
, (DWORD) PAGE_READWRITE /* desired access protection */
, (PDWORD) &OldProtect /* address of variable to get old protection */
);
if (0 == ret)
mprotectFailed();
address = ((char *)address) + tail_size;
size -= tail_size;
}
#else
if ( mprotect((caddr_t)address, size, PROT_READ|PROT_WRITE) < 0 )
mprotectFailed();
#endif
}
/* Function: Page_DenyAccess
*
* Deny access to allocated memory region.
*
* See Also:
* <Page_AllowAccess>
*/
static void Page_DenyAccess(void * address, size_t size)
{
#if defined(WIN32)
SIZE_T OldProtect, retQuery;
MEMORY_BASIC_INFORMATION MemInfo;
size_t tail_size;
BOOL ret;
while (size >0)
{
retQuery = VirtualQuery(address, &MemInfo, sizeof(MemInfo));
if (retQuery < sizeof(MemInfo))
DUMA_Abort("VirtualQuery() failed\n");
tail_size = (size > MemInfo.RegionSize) ? MemInfo.RegionSize : size;
ret = VirtualProtect(
(LPVOID) address /* address of region of committed pages */
, (DWORD) tail_size /* size of the region */
, (DWORD) PAGE_NOACCESS /* desired access protection */
, (PDWORD) &OldProtect /* address of variable to get old protection */
);
if (0 == ret)
mprotectFailed();
address = ((char *)address) + tail_size;
size -= tail_size;
}
#else
if ( mprotect((caddr_t)address, size, PROT_NONE) < 0 )
mprotectFailed();
#endif
}
/* Function: Page_Delete
*
* Free's DUMA allocated memory. This is the real deal, make sure
* the page is no longer in our slot list first!
*
* See Also:
* <Page_Create>
*/
static void Page_Delete(void * address, size_t size)
{
#if defined(WIN32)
void * alloc_address = address;
SIZE_T retQuery;
MEMORY_BASIC_INFORMATION MemInfo;
BOOL ret;
/* release physical memory commited to virtual address space */
while (size >0)
{
retQuery = VirtualQuery(address, &MemInfo, sizeof(MemInfo));
if (retQuery < sizeof(MemInfo))
DUMA_Abort("VirtualQuery() failed\n");
if ( MemInfo.State == MEM_COMMIT )
{
ret = VirtualFree(
(LPVOID) MemInfo.BaseAddress /* base of committed pages */
, (DWORD) MemInfo.RegionSize /* size of the region */
, (DWORD) MEM_DECOMMIT /* type of free operation */
);
if (0 == ret)
DUMA_Abort("VirtualFree(,,MEM_DECOMMIT) failed: %s", stringErrorReport());
}
address = ((char *)address) + MemInfo.RegionSize;
size -= MemInfo.RegionSize;
}
/* release virtual address space */
ret = VirtualFree(
(LPVOID) alloc_address
, (DWORD) 0
, (DWORD) MEM_RELEASE
);
if (0 == ret)
DUMA_Abort("VirtualFree(,,MEM_RELEASE) failed: %s", stringErrorReport());
#else
if ( munmap((caddr_t)address, size) < 0 )
Page_DenyAccess(address, size);
#endif
}
/* Function: Page_Size
*
* Retrieve page size.
*/
static size_t
Page_Size(void)
{
#if defined(WIN32)
SYSTEM_INFO SystemInfo;
GetSystemInfo( &SystemInfo );
return (size_t)SystemInfo.dwPageSize;
#elif defined(_SC_PAGESIZE)
return (size_t)sysconf(_SC_PAGESIZE);
#elif defined(_SC_PAGE_SIZE)
return (size_t)sysconf(_SC_PAGE_SIZE);
#else
/* extern int getpagesize(); */
return getpagesize();
#endif
}
#endif /* DUMA_PAGING_H */

405
third_party/duma/print.c vendored Normal file
View file

@ -0,0 +1,405 @@
/*
* DUMA - Red-Zone memory allocator.
* Copyright (C) 2006 Michael Eddington <meddington@gmail.com>
* Copyright (C) 2002-2008 Hayati Ayguen <h_ayguen@web.de>, Procitec GmbH
* Copyright (C) 1987-1999 Bruce Perens <bruce@perens.com>
* License: GNU GPL (GNU General Public License, see COPYING-GPL)
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
* FILE CONTENTS:
* internal implementation file
* contains aborting, printing functions with minor system/platform dependencies
*/
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <stdarg.h>
#ifndef WIN32
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/param.h>
#else
#define WIN32_LEAN_AND_MEAN 1
#include <windows.h>
#include <winbase.h>
#include <io.h>
#ifndef __CYGWIN__
/* already defined in cygwin headers */
typedef LPVOID caddr_t;
#else
/* use these for cygwin */
#include <unistd.h>
#include <fcntl.h>
#endif
#endif
#ifdef _MSC_VER
#include <crtdbg.h>
#endif
#include "duma.h"
#include "noduma.h"
#include "print.h"
/*
* NBBY is the number of bits per byte. Some systems define it in <sys/param.h>
*/
#ifndef NBBY
#define NBBY 8
#endif
/*
* These routines do their printing without using stdio. Stdio can't
* be used because it calls malloc(). Internal routines of a malloc()
* debugger should not re-enter malloc(), so stdio is out.
*/
/* define prototypes / forward declarations */
static int sprintAddr(char* dest, DUMA_ADDR addr, DUMA_ADDR base);
static int sprintLong(char* dest, long number, long base);
static int DUMA_vsprintf(char* buffer, const char *pattern, va_list args);
/*
* NUMBER_BUFFER_SIZE is the longest character string that could be needed
* to represent an unsigned integer, assuming we might print in base 2.
* Any other representation (base 10 or 16) will need less characters.
*/
#define NUMBER_BUFFER_SIZE (sizeof(DUMA_ADDR) * NBBY)
#define STRING_BUFFER_SIZE 4096
/* Function: sprintAddr
*
* internal function to print a DUMA_ADDR into a buffer
*/
static int sprintAddr(char* dest, DUMA_ADDR value, DUMA_ADDR base)
{
char buffer[NUMBER_BUFFER_SIZE+1];
char * s = &buffer[NUMBER_BUFFER_SIZE];
int size;
DUMA_ADDR digit;
do
{
if ( --s == buffer )
DUMA_Abort("Internal error printing number.");
digit = value % base;
*s = (char)( (digit < 10) ? ('0' + digit) : ('a' + digit -10) );
} while ( (value /= base) > 0 );
size = &buffer[NUMBER_BUFFER_SIZE] - s;
buffer[NUMBER_BUFFER_SIZE] = '\0';
strcpy(dest, s);
return size;
}
/* Function: sprintLong
*
* internal function to print a int into a buffer
*/
static int sprintLong(char* dest, long value, long base)
{
char buffer[NUMBER_BUFFER_SIZE+1];
char * s = &buffer[NUMBER_BUFFER_SIZE];
long size;
long digit;
do
{
if ( --s == buffer )
DUMA_Abort("Internal error printing number.");
digit = value % base;
*s = (char)( (digit < 10) ? ('0' + digit) : ('a' + digit -10) );
} while ( (value /= base) > 0 );
size = &buffer[NUMBER_BUFFER_SIZE] - s;
buffer[NUMBER_BUFFER_SIZE] = '\0';
strcpy(dest, s);
return size;
}
/* Function: DUMA_vsprintf
*
* internal function to print a formatted string into a buffer
* int sprintf(char* buffer, const char *pattern, va_list args)
* allowed format specifier are:
*
* %a = adress of type DUMA_ADDR
* %x = adress of type DUMA_ADDR
* %d = unsigned of type DUMA_SIZE
* %i = int
* %l = long
* %s = string teminated with '\0'
* %c = char
*/
static int DUMA_vsprintf(char* buffer, const char *pattern, va_list args)
{
char c;
static const char bad_pattern[] = "\nDUMA: Bad pattern specifier %%%c in DUMA_Print().\n";
const char * s = pattern;
int len = 0;
DUMA_ADDR n;
c = *s++;
while ( c )
{
if ( c == '%' )
{
c = *s++;
switch ( c )
{
case '%':
buffer[len++] = c;
break;
case 'a': /* DUMA_ADDR */
case 'x': /* DUMA_ADDR */
/*
* Print an address passed as a void pointer.
* The type of DUMA_ADDR must be set so that
* it is large enough to contain all of the
* bits of a void pointer.
*/
n = va_arg(args, DUMA_ADDR);
len += sprintAddr(&buffer[len], n, 16);
break;
case 'd': /* DUMA_SIZE */
n = va_arg(args, DUMA_SIZE);
len += sprintAddr(&buffer[len], n, 10);
break;
case 'i': /* int */
{
long n = (long)va_arg(args, int);
if ( n < 0 )
{
buffer[len++] = '-';
n = -n;
}
len += sprintLong(&buffer[len], n, 10);
break;
}
case 'l': /* long */
{
long n = va_arg(args, long);
if ( n < 0 )
{
buffer[len++] = '-';
n = -n;
}
len += sprintLong(&buffer[len], n, 10);
break;
}
case 's': /* string */
{
const char * string;
size_t length;
string = va_arg(args, char *);
if (string)
{
length = strlen(string);
strcpy(&buffer[len], string);
}
else
{
length = 4; /* = strlen("NULL") */
strcpy(&buffer[len], "NULL");
}
len += length;
break;
}
case 'c': /* char */
/* characters are passed as int ! */
buffer[len++] = (char)va_arg(args, int);
break;
default:
DUMA_Print(bad_pattern, c);
}
}
else /* if ( c != '%' ) */
buffer[len++] = c;
c = *s++;
} /* end while (c) */
buffer[len] = '\0';
return len;
}
/* Function: DUMA_Abort
*
* external abort function
* on Visual C++ it additionally prints to Debug Output of the IDE
* void DUMA_Abort(const char * pattern, ...)
*/
void
DUMA_Abort(const char * pattern, ...)
{
char buffer[STRING_BUFFER_SIZE];
int lena, lenb;
va_list args;
va_start(args, pattern);
strcpy(buffer, "\nDUMA Aborting: ");
lena = strlen(buffer);
lenb = DUMA_vsprintf(&buffer[lena], pattern, args);
strcat(buffer, "\n");
DUMA_Print("%s", buffer);
va_end(args);
#ifndef WIN32
/*
* I use kill(getpid(), SIGILL) instead of abort() because some
* mis-guided implementations of abort() flush stdio, which can
* cause malloc() or free() to be called.
*/
kill(getpid(), SIGILL);
#else
/* Windows doesn't have a kill() */
abort();
#endif
/* Just in case something handles SIGILL and returns, exit here. */
_exit(-1);
}
/* Function: DUMA_Print
*
* external print function
* on Visual C++ it additionally prints to Debug Output of the IDE
* void DUMA_Print(const char * pattern, ...)
*/
void
DUMA_Print(const char * pattern, ...)
{
char buffer[STRING_BUFFER_SIZE];
int len, fd;
va_list args;
va_start(args, pattern);
len = DUMA_vsprintf(buffer, pattern, args);
va_end(args);
#ifdef WIN32
if(DUMA_OUTPUT_DEBUG)
OutputDebugString(buffer);
#endif
if(DUMA_OUTPUT_STDOUT)
write(1, buffer, len);
if(DUMA_OUTPUT_STDERR)
write(2, buffer, len);
if(DUMA_OUTPUT_FILE != NULL)
{
#if defined(WIN32) && !defined(__CYGWIN__)
fd = _open(DUMA_OUTPUT_FILE, _O_APPEND|_O_CREAT|_O_WRONLY);
#else
fd = open(DUMA_OUTPUT_FILE, O_APPEND|O_CREAT|O_WRONLY);
#endif
if ( fd >= 0 )
{
write(fd, buffer, len);
#if defined(WIN32) && !defined(__CYGWIN__)
_close(fd);
#else
close(fd);
#endif
}
}
}
/* Function: DUMA_Exit
*
* external exit function
* on Visual C++ it additionally prints to Debug Output of the IDE
* void DUMA_Exit(const char * pattern, ...)
*/
void
DUMA_Exit(const char * pattern, ...)
{
char buffer[STRING_BUFFER_SIZE];
int lena, lenb;
va_list args;
va_start(args, pattern);
strcpy(buffer, "\nDUMA Exiting: ");
lena = strlen(buffer);
lenb = DUMA_vsprintf(&buffer[lena], pattern, args);
strcat(buffer, "\n");
DUMA_Print("%s", buffer);
#ifdef WIN32
if(DUMA_OUTPUT_DEBUG)
OutputDebugString(buffer);
#endif
va_end(args);
/*
* I use _exit() because the regular exit() flushes stdio,
* which may cause malloc() or free() to be called.
*/
_exit(-1);
}
/* Function: DUMA_sprintf */
void
DUMA_sprintf(char* buffer, const char * pattern, ...)
{
int len;
va_list args;
va_start(args, pattern);
len = DUMA_vsprintf(buffer, pattern, args);
va_end(args);
if (len <= 0)
buffer[0] = 0;
}
const char *
DUMA_strerror(int duma_errno)
{
static char acStrError[STRING_BUFFER_SIZE];
DUMA_sprintf(acStrError, "System Error Number 'errno' from Standard C Library is %i\n", duma_errno);
return acStrError;
}
/* end */

51
third_party/duma/print.h vendored Normal file
View file

@ -0,0 +1,51 @@
/*
* DUMA - Red-Zone memory allocator.
* Copyright (C) 2002-2008 Hayati Ayguen <h_ayguen@web.de>, Procitec GmbH
* Copyright (C) 1987-1999 Bruce Perens <bruce@perens.com>
* License: GNU GPL (GNU General Public License, see COPYING-GPL)
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
* FILE CONTENTS:
* internal header file
* contains aborting, printing functions with minor system/platform dependencies
*/
#ifndef DUMA_PRINT_H
#define DUMA_PRINT_H
/*
* These routines do their printing without using stdio. Stdio can't
* be used because it calls malloc(). Internal routines of a malloc()
* debugger should not re-enter malloc(), so stdio is out.
*/
#ifdef __cplusplus
extern "C" {
#endif
void DUMA_Abort(const char * pattern, ...);
void DUMA_Print(const char * pattern, ...);
void DUMA_Exit(const char * pattern, ...);
void DUMA_sprintf(char* buffer, const char * pattern, ...);
const char * DUMA_strerror(int duma_errno);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* DUMA_PRINT_H */

288
third_party/duma/sem_inc.c vendored Normal file
View file

@ -0,0 +1,288 @@
/*
* DUMA - Red-Zone memory allocator.
* Copyright (C) 2002-2008 Hayati Ayguen <h_ayguen@web.de>, Procitec GmbH
* License: GNU LGPL (GNU Lesser General Public License, see COPYING-GPL)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* FILE CONTENTS:
* internal implementation file
* contains thread safety functions (semaphore lock/release)
*/
#include "duma_config.h"
#include "duma_sem.h"
#include "print.h"
#include <stdlib.h>
#ifndef DUMA_NO_THREAD_SAFETY
/* check for pthread library */
/* use WIN32_SEMAPHORES on Win32-Cygwin,
* with this configuration testmt.c works either with pthreads and with the Win32 API
*/
/* || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__)) */
#if (!defined(WIN32))
#define HAVE_PTHREADS 1
#define USE_WIN32_SEMAPHORES 0
#define USE_WIN32_CRIT_SECT 0
#else
#define HAVE_PTHREADS 0
#define USE_WIN32_SEMAPHORES 1
#define USE_WIN32_CRIT_SECT 0
#endif
#if HAVE_PTHREADS
#include <pthread.h>
#include <semaphore.h>
#elif USE_WIN32_SEMAPHORES || USE_WIN32_CRIT_SECT
#define WIN32_LEAN_AND_MEAN 1
#include <windows.h>
#include <winbase.h>
#endif
/*
* DUMA_sem is a semaphore used to allow one thread at a time into
* these routines.
* Also, we use semInited as a boolean to see if we should be
* using the semaphore.
* semThread is set to the thread id of the thread that currently
* has the semaphore so that when/if it tries to get the semaphore
* again (realloc calling malloc/free) - nothing will happen to the
* semaphore.
* semDepth is used to keep track of how many times the same thread
* gets the semaphore - so we know when it is actually freed.
*/
#if HAVE_PTHREADS
#define DUMA_thread_self() pthread_self()
#ifndef DUMA_SEMAPHORES
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_t mutextid=0;
static int locknr=0;
#else
static sem_t DUMA_sem = { 0 };
static pthread_t semThread = (pthread_t) 0;
#endif
#elif USE_WIN32_SEMAPHORES
#define DUMA_thread_self() GetCurrentThreadId()
#ifndef UNICODE
#define SEM_NAME_TYPE char
#define SEM_STRCPY strcpy
#define SEM_STRCAT strcat
static char semObjectName[] = "DUMA_";
#else
#define SEM_NAME_TYPE wchar_t
#define SEM_STRCPY wcscpy
#define SEM_STRCAT wcscat
static wchar_t semObjectName[] = L"DUMA_";
#endif
static SECURITY_ATTRIBUTES semSecAttr;
static DWORD semThread = 0;
static HANDLE semHandle = 0;
#elif USE_WIN32_CRIT_SECT
/* see http://msdn.microsoft.com/en-us/library/ms682530(VS.85).aspx */
static CRITICAL_SECTION critsect;
#endif
static int semInInit = 0;
#if HAVE_PTHREADS && !defined(DUMA_SEMAPHORES)
static int semInited = 1;
static int semDepth = 0;
#elif USE_WIN32_SEMAPHORES
static int semInited = 0;
static int semDepth = 0;
#elif USE_WIN32_CRIT_SECT
static int semInited = 0;
#endif
#if HAVE_PTHREADS
#ifndef DUMA_SEMAPHORES
static void lock()
{
if (pthread_mutex_trylock(&mutex))
{
if ( mutextid==pthread_self() )
{
++locknr;
return;
}
else
{
pthread_mutex_lock(&mutex);
}
}
mutextid=pthread_self();
locknr=1;
}
static void unlock()
{
--locknr;
if (!locknr)
{
mutextid=0;
pthread_mutex_unlock(&mutex);
}
}
#endif
#endif
void
DUMA_init_sem(void)
{
#if USE_WIN32_SEMAPHORES
SEM_NAME_TYPE semLocalName[32];
SEM_NAME_TYPE acPID[16];
DWORD pid;
#endif
/* avoid recursive call to sem_init(),
* when sem_init() calls malloc() or other allocation function
*/
if (semInited || semInInit)
return;
semInInit = 1;
#if HAVE_PTHREADS
#ifndef DUMA_SEMAPHORES
pthread_mutex_init(&mutex, NULL);
semInited = 1;
#else
if (sem_init(&DUMA_sem, 0, 1) >= 0)
semInited = 1;
#endif
#elif USE_WIN32_SEMAPHORES
pid = GetCurrentProcessId();
SEM_STRCPY(semLocalName, semObjectName);
/* append ProcessId() to get inter-process unique semaphore name */
acPID[0] = 'A' + (SEM_NAME_TYPE)( (pid >> 28) & 0x0F );
acPID[1] = 'A' + (SEM_NAME_TYPE)( (pid >> 24) & 0x0F );
acPID[2] = 'A' + (SEM_NAME_TYPE)( (pid >> 20) & 0x0F );
acPID[3] = 'A' + (SEM_NAME_TYPE)( (pid >> 16) & 0x0F );
acPID[4] = 'A' + (SEM_NAME_TYPE)( (pid >> 12) & 0x0F );
acPID[5] = 'A' + (SEM_NAME_TYPE)( (pid >> 8) & 0x0F );
acPID[6] = 'A' + (SEM_NAME_TYPE)( (pid >> 4) & 0x0F );
acPID[7] = 'A' + (SEM_NAME_TYPE)( (pid ) & 0x0F );
acPID[8] = 0;
SEM_STRCAT( semLocalName, acPID );
semSecAttr.nLength = sizeof(semSecAttr);
semSecAttr.lpSecurityDescriptor = NULL;
semSecAttr.bInheritHandle = FALSE;
semHandle = CreateSemaphore( &semSecAttr /* pointer to security attributes */
, 1 /* initial count */
, 1 /* maximum count */
, semLocalName /* pointer to semaphore-object name */
);
semInited = 1;
#elif USE_WIN32_CRIT_SECT
InitializeCriticalSection(&critsect);
semInited = 1;
#endif
semInInit = 0;
if (!semInited) DUMA_Abort("\nCouldn't initialise semaphore");
}
void DUMA_get_sem(void)
{
if (semInInit) return; /* avoid recursion */
if (!semInited) DUMA_init_sem(); /* initialize if necessary */
#if HAVE_PTHREADS
#ifndef DUMA_SEMAPHORES
lock();
#else
if (semThread != DUMA_thread_self())
{
while (sem_wait(&DUMA_sem) < 0); /* wait for the semaphore. */
semThread = DUMA_thread_self(); /* let everyone know who has the semaphore. */
}
#endif
++semDepth; /* increment semDepth - push one stack level */
#elif USE_WIN32_SEMAPHORES
if (semThread != DUMA_thread_self())
{
while (WaitForSingleObject(semHandle, 1000) != WAIT_OBJECT_0) ; /* wait for the semaphore. */
semThread = DUMA_thread_self(); /* let everyone know who has the semaphore. */
}
++semDepth; /* increment semDepth - push one stack level */
#elif USE_WIN32_CRIT_SECT
EnterCriticalSection(&critsect);
#endif
}
int DUMA_rel_sem(int retval)
{
if (semInInit) return retval; /* avoid recursion */
if (!semInited) DUMA_Abort("\nSemaphore isn't initialised");
#ifdef DUMA_SEMAPHORES
if (!semThread) DUMA_Abort("\nSemaphore isn't owned by this thread");
#endif
#if HAVE_PTHREADS || USE_WIN32_SEMAPHORES
if (semDepth <= 0) DUMA_Abort("\nSemaphore isn't locked");
#endif
--semDepth; /* decrement semDepth - popping one stack level */
#if HAVE_PTHREADS
#ifndef DUMA_SEMAPHORES
unlock();
#else
semThread = (pthread_t) 0; /* zero this before actually free'ing the semaphore. */
if (sem_post(&DUMA_sem) < 0)
DUMA_Abort("Failed to post the semaphore.");
#endif
#elif USE_WIN32_SEMAPHORES
semThread = 0; /* zero this before actually free'ing the semaphore. */
if (0 == ReleaseSemaphore(semHandle, 1 /* amount to add to current count */, NULL) )
DUMA_Abort("Failed to post the semaphore.");
#elif USE_WIN32_CRIT_SECT
LeaveCriticalSection(&critsect);
#endif
return retval;
}
#else
/* for not having an empty file */
static int dummy = 0;
#endif /* DUMA_NO_THREAD_SAFETY */

20
third_party/duma/wscript vendored Normal file
View file

@ -0,0 +1,20 @@
def configure(conf):
pass
def build(bld):
if 'DUMA_DISABLED' in bld.env.DEFINES:
return
import sys
defines = []
if 'linux' in sys.platform:
defines.append('_POSIX_C_SOURCE')
elif 'darwin' in sys.platform:
defines.append('DUMA_SO_PREFER_GETENV')
bld.stlib(source=['duma.c', 'print.c', 'sem_inc.c'],
defines=defines,
target='duma')
# vim:filetype=python