The Common Weakness Enumeration (CWE) list at http://cwe.mitre.org/ is a community-created living dictionary of software weaknesses -- that is, *types* of weaknesses. This dictionary and Top 25 list involved experts from the computer industry, academia, the SANS Institute, the non-profit MITRE Corporation, the NSA, and the Department of Homeland Security. The goal of their initiative is to establish standards for assessment and verification of security vulnerabilities in software and the security tools that mitigate those weaknesses. Simply put, they just want to make computer security measurable.
Currently the CWE lists 755 total weaknesses (note a few are deprecated duplicates). They leveraged previous work from the deep CVE (Common Vulnerabilities and Exposures) list at http://cve.mitre.org/cve/index.html , which is a large dictionary of specific publicly known vulnerabilities (these generally look like "Buffer overflow in Bar 5.0 in Foo OS 3"). The CVE lists over 3000 confirmed specific vulnerabilities and tens of thousands more candidate vulnerabilities. So, the CWE lists types of vulnerabilities, and you could say these are abstractions of specific entries from the CVE (as well as a variety of other sources).
So, bubbling to the top of the CWE is their Top 25 Most Dangerous Programming Errors. These are noteworthy errors that can lead to hacked systems, data theft, and system inoperability. Importantly, security exploits rooted to these errors can be easy to code. Each error is in one of three categories, and these examples will be familiar to some:
The SANS Institute believes this Top 25 list will enable buyers (for example state and US government) to buy safer software, where vendors will need to certify by checking for these errors. Universities can also teach secure coding by a set standard, and software developers and their employers will have greater assurance regarding security vulnerabilities in their software projects. This gets to the root of cyber-security problems at the source, in software development.
What should you take away from this list? Here are some higher level takeaways and implications:
1. If you develop software, educate yourself on these vulnerabilities and the programming techniques to help mitigate them. Developers should make a reasonable effort to design security in from the beginning of their projects. A large number of programmers today work on web serving applications, like e-commerce, which requires identity management, secure transactions, and secure record-keeping. For consumer confidence, security’s clearly going to be a significant concern -- more so than performance or scalability. And remember that secure programming skills are a desired requirement in many job postings.
2. If you don’t develop software directly, educate yourself at least at a high level on these vulnerabilities anyway. You don’t need to be paranoid, but some realistic awareness is healthy. Think about how you manage your confidential data on your computers, whether the data is personal or professional. A good way to get started here is to take a look at the SANS Top-20 Security Risks at http://www.sans.org/top20/. This covers diverse risks applicable to everyone, like unsecured flash drives, web browser vulnerabilities, denial-of-service attacks due to instant messaging, and so forth.
3. For the IT manager crafting an IT infrastructure, the challenge is even broader, with considerations such as risk assessment, vulnerability assessments, and regulatory compliance. All these can be looked at through the lens of the SANS Top 25 Most Dangerous Programming Errors. Remember the goal behind the CWE effort is to make software security measurable, and the Top 25 List is a focal point for that goal.
-------------------------
Tracy Carver, MTS Software Engineer
The information presented in this document is for informational purposes only and may contain technical inaccuracies, omissions and typographical errors. Links to third party sites are for convenience only, and no endorsement is implied.
Well, I may have managed to avoid watching "It's a Wonderful Life" last month, but I can't say the same about avoiding holiday cookies. I've just come off of enough of my seasonal sugar high to be able to construct actual sentences, so that I can tell you about the great trip that I had to NY on 12/17.
First, I had a good chat with David Worthington of the SD Times, who put together an article discussing AMD's Java optimization efforts. It highlights some of the short and long term optimization goals that we have.
That evening, I presented "Run Anywhere: The Hardware Platform Perspective" at the NY JavaSIG. Mainly, it's an introduction to the work that we do in the Java Labs, and an overview of tuning options from a hardware point-of-view. Many thanks to Google, who hosted the space for the meeting, to the great NY JavaSIG audience, and a special shout out to Eric Bruno, who blogged about it on Dr. Dobb's CodeTalk
Overall, a successful trip. I even got to see some snow before getting back to warmer climes.
Ben
-------------------------
The information presented in this document is for informational purposes only and may contain technical inaccuracies, omissions and typographical errors. Links to third party sites are for convenience only, and no endorsement is implied.
Many Java applications, especially those using large heaps, can benefit from what the operating systems call large or huge pages. In the x86 architecture, these are pages that are larger than the default 4K byte pages, usually 2MB. See the article Supersizing Java: Large Pages on the Opteron Processor for a discussion of these huge pages and how to set up your OS and JVM to use them.
But what if you are specifically using huge pages in a NUMA environment and you intend to run multiple JVMs each affinitized to a node? For maximum performance you would like to make sure the huge pages are balanced across the nodes of the system. In the following we discuss some finer points of huge pages and NUMA. The behavior and utilities available are different across Linux® and Windows®-based systems.
Huge Pages and NUMA on Linux®
On Linux, as described in the Supersizing article, you have to first reserve the huge pages (by a command such as echo nnn >/proc/sys/vm/nr_hugepages) before an application like a JVM can use them. Since huge pages need to be locked in memory, the write to nr_hugepages actually allocates the pages, and holds them in a pool. This reserved huge page memory cannot then be used for small pages. By reading back nr_hugepages, you can see whether you got the number of huge pages you asked for. (Note that you won’t see an error message on the write, so you won’t know how many huge pages you got unless you read it back). This is all fine, but what if we want to know not only how many huge pages we got, but also what nodes they were attached to?
This information is available thru the command cat /sys/devices/system/node/node*/meminfo. For each node, you are shown the HugePages_Total and the HugePages_Free. So after reserving thru nr_hugepages, you should see the HugePages_Free on the nodes in the system adding up to the total number of hugepages you asked for. And you would want those HugePages_Free to be distributed evenly across the nodes.
The default allocation policy (maybe the only one) is to go from node to node in a round robin fashion looking for a free 2MB chunk of memory and placing it in the pool. However, the important point is that if one node has no more free 2MB chunks of contiguous memory available, the reservations will continue on other nodes until the required nr_hugepages are reserved or until no more hugepages can be found on any node. This makes sense because when you write to nr_hugepages, the system doesn’t know whether you’re later going to use those huge pages from affinitized processes or not.
The above logic holds true when you’re increasing the number of huge pages. However, if you’re reducing the number of huge pages, the behavior is less sensible in that the OS will free up as many pages as possible from node 0, then as many as possible from node 1, etc. until you’ve freed up the required number of pages. Thus, if you want to reduce the number of huge pages and still have them balanced across nodes, first reduce them to zero, and then increase them to the number you really want.
On Linux, when an application that has been affinitized using –membind wants to allocate a huge page from the pool, it is only allowed to allocate from the pool local to the node (or nodes) it’s been affinitized to. If the application asks for more pages than are available on that node, it will fail rather than just allocate an unused page from the pool of some other node. In a way this is good because if you went to the trouble of affinitizing you wanted the pages to be local and there are advantages to failing early and letting you fix the page allocation problem rather than running with non-local pages at possibly lower performance.
In general huge page reservation should be done as early as possible before the memory gets fragmented which would result in fewer contiguous 2MB chunks being available. But the methods above can let you know whether a later reservation will meet your needs or not.
In our next entry, we’ll look at how Windows-based systems handle huge pages and NUMA. Meanwhile, I’d be interested in cases where people have actually used huge pages and affinity on Linux.
-------------------------
The information presented in this document is for informational purposes only and may contain technical inaccuracies, omissions and typographical errors. Links to third party sites are for convenience only, and no endorsement is implied.
Tracing a performance problem back to source code is a common task in performance analysis. Tools that automate this task can save engineers plenty of manual labor. Though there are many Java tools that perform source mapping, they arguably have limited accuracy because JVMTI, the interface that they rely on, lacks information about inlining decisions. JVMTI does not know whether the code that the JVM generates for a compiled method belongs to the method itself or to another method that was inlined into it.
In a previous blog article ("Inlining Information Hidden in the Hotspot JVM"), I mentioned that we have found a way to expose to tool writers the inlining information that is inside the Hotspot JVM, paving the way for more accurate source mapping. However, I didn't describe how we implemented our approach. The way you solve a software problem can open the door to solving other software problems than the one that you had originally targeted.
Initially, we wanted to solve the problem of improved source mapping. We knew that the Hotspot JVM contained information about inlining decisions, and that this information was unavailable to tool writers. We wanted to expose this information to tool writers.
Naturally, the first place to look was the JVMTI interface, since this is the interface that is used to pass information between the JVM and external tools. Through this interface, the JVM emits events (such as CompiledMethodLoad and ClassFileLoadEvent) to inform external tools about the different phases that it is in. For example, whenever it compiles a method, it emits a CompiledMethodLoadEvent, which contains information about the method that was compiled. External tools (e.g., JVMTI agents) can process these events to do things like printing the names of the methods that the JVM compiled, or the names of the classes that were loaded.
The interesting thing about the CompiledMethodLoad callback is that it contains a void pointer that the JVM does not use. This led us to our solution: Whenever a method is compiled, we could simply attach its inlining information to this pointer, thereby allowing this information to be passed outside the JVM via the CompiledMethodLoad event.
What's nice about this mechanism is that it doesn't alter the JVMTI spec, and that it is reusable. Although this mechanism allows us to expose inlining information, we could in the future use it to expose other kinds of information, such as register allocation information or information about optimization decisions. So while our changes benefit source-to-address mapping, they can have more widespread applications.
What other applications do you see benefiting from our approach? And to those of you who are writing Java tools, what additional information do you wish you had, which is currently unavailable to you since it is inside the JVM?
-------------------------
Vasanth Venkatachalam
The information presented in this document is for informational purposes only and may contain technical inaccuracies, omissions and typographical errors. Links to third party sites are for convenience only, and no endorsement is implied.
Edited: 08/18/2009 at 10:39 AM by AMD Developer Blogs Moderator
When troubleshooting a performance problem, we often want to know what part of a program's source code caused the problem in the first place. Luckily, in the case of Java source, there are numerous tools that simplify this process by displaying the compiled code and source code for a method side-by-side. These Java analysis tools rely on the Java Virtual Machine Tools Interface (JVMTI) to capture information about how a program's source code maps to the compiled code.
One limitation of JVMTI is that when a method is compiled, the methods that it calls may be inlined into its own body.
For example, consider the following code snippet:
int foo(int j)
{
return j+1;
}
public static void main(String[] args)
{
for(int i = 0; i < 3; i++)
{
j += foo(j);
}
}
The JVM is smart enough to see that the work being done inside the function foo is trivial (the incrementing of a counter), and that it would be less expensive to execute the code for foo as part of the code for main than to execute a separate procedure call to foo. As a result, the JVM will inline the code for foo into the code it generates for main. (Actually, the JVM could go a step further in this simple example, and directly compute the final value of j.)
Inlining raises a problem for JVMTI because JVMTI has no way of knowing whether the code generated for a method belongs to the method itself or to other methods that were called and inlined into it. This makes it difficult to tell which part of a program's source code is ultimately responsible for a performance bottleneck.
At JavaLabs, we are prototyping a software process to solve this problem. The main idea is that the Hotspot JVM contains hidden information about methods that are inlined. We have found a way to make this information visible to external tools through the JVMTI layer, without altering the JVMTI specification.
You may be wondering what our secret is. When the Hotspot JVM compiles a method, it creates a list of records that tell you what methods are on the compile time stack at every program address. This indirectly tells you what methods have been inlined; these are the methods that don't have call instructions in the disassembled code. You can view this inlining information by running Hotspot in debug mode with the command line option, -XX:+PrintNMethods.
We have extended Hotspot to pass this stack information into the CompiledMethodLoad JVMTI callback. As a result, tools can use this information to produce better source-to-address mapping.
As a next step, we'll be extending tools that AMD has developed (e.g., CodeSleuth, AMD Code Analyst) to exploit this inlining information. We also plan to contribute our Hotspot changes to the Open JDK. Stay tuned for more details.
-------------------------
Vasanth Venkatachalam
The information presented in this document is for informational purposes only and may contain technical inaccuracies, omissions and typographical errors. Links to third party sites are for convenience only, and no endorsement is implied.