This is a random item from my wishlist:
Gentleman And The Far East Band Live.
The full list is on amazon.de
Related tags
.net c# php security web 2.0 xss anniversary fun php extensions php shell readline assembler boredom frustration stupidity banshee music BarCamp conferences debugging dtrace events macos opensolaris planet php solaris travel wolfram bazaar java launchpad netbeans phpqa phpt balcony blogging entertainment fire fire at home fire fighters home sweet home internet irc same proocedure trends tv tv series twitter video youtube Bryan Cantrill development DTrace google MacOS sun microsystems exchange microsoft office outlook outlookfun vba christmas escher family games mysql mysql storage engine pony puzzle weihnachten comments english german language 23c3 acquisation berlin blogger ccc data center ego froscon froscon08 hamburg hausdurchsuchung ipc ipc06 ipc07 ipc08 ipc09 james gosling lawblog montreal namespaces nuremberg osdc osdc.il07 osdc09 php conferences php quebec php quebec 09 php releases php53 recht und ordnung st. augustin train ulf cvs dsp git parsecvs play project managment scm vcs barcamp gopal pecl releases scream delphi pascal gsoc gsoc09 improvements ms paint mysqlnd packages paint php testing testing unicode ajax amber road blog brendand gregg crossbow hardware linux server solaris zones storage virtualization zfs zones exams university beer garden munich php bbq firefox gecko mozilla xul javafx badeente barcelona catalonia concert dancehall daten frei dendemann earth god google maps hiphop history job kaffee kaunas kinderzimmer productions linkblog lithuania live beate merk br alpha bundesdatenschutzbeauftragter bundestrojaner bundesverfassungsgericht cdu csu Daten frei datenschutz gmail gsoc08 movies onlinedursuchung patriot act politik privacy regierung schäuble sicherheitsstaat terroristen urteilvorratsdatenspeicherung goto closures php qa php testfest easter gsoc2008 qa testfest bc mysql proxy phpmysqlproxy work iterator mysqli resultset stored procedures array grades jee xenjo windows open air rap seeed
In a previous blog post I mentioned the possibility for using non ASCII characters as part of identifiers. Nils Langner, who runs the German "PHP hates me (but that's ok)" blog, then wondered whether it makes sense to use German (in his case) terms for identifiers in code in the comments it was also discussed what language is best to be used in comments.
The argument for using only English is simple: Every developer should know at least basic English and using English helps when either outsourcing, opensourcing or reaching new markets.
Now there are arguments against English, too, one is that not all developers are able of using English properly so reading and writing comments is more difficult for them - now you don't have to write long prosaic texts in comments, but still ...
The other argument goes by domain-specific terminology. In some cases - for instance when bound to legal environments - such terms can't be translated properly. For instance when dealing with financial data accounting by US-GAAP differs in many parts from the German accounting rules: For some positions you find translations which have the same meaning but are calculated slightly different so using the English term would imply the values would be calculated by the US rules (sorry British folks for this example - I have no idea about the British terminology and accounting rules, but have basic understanding of German rules and US-GAAP
). Ignoring this problem you still have to consider that you'd still talk German to your customer so the customer would use German terminology and you have to keep a dictionary for these terms which is a pain for everybody involved.
So now one could use mostly English with some local terms which gives a nice mixture ("function getEigenkapitalrendite()") or invent complete new terminology ("function erhalteEigenkapitalrendite()") which is stupid in comments, too ("The Eigenkapitalrendite is depending on the Gewinn and the Eigenkapital") ...
Now I'm in the "lucky" position that most things I do these days are either done for some American company or a popular world wide used open source project and is mostly about stuff where the typical terminology is English so I can use my bad English everywhere - but I'm curious what others are doing and what others think.
PHP 5.3 is released and after the release stress is over my mind is open for new ideas. While relaxing yesterday I thought about many things, among them was the Resultset iterator I recently discussed.
Now I wondered where to go next with this and had the idea that an individual Resultset is a child of the whole result and this might be wrapped in an Recursive Iterator. For doing so we don't implement the Iterator interface but RecursiveIterator. RecursiveIterator extends a typical Iterator with two methods: hasChildren() and getChildren(). But now we have a problem: The Iterator returned by getChildren() has to be a RecursiveIterator, too, which makes sense, in general. But I want to return a MySQLi Resultset which isn't recursive - so making this a RecursiveIterator is wrong. My solution now is to introduce yet another Iterator which goes by the name of MySQLi_PseudoRecursiveResultIterator and is implemented by extending IteratorIterator which will wrap the MySQLi_Result and implements RecursiveIterator telling the caller that there are no children.
As a sidenote: In our experimental tree Andrey made MySQLi_Result an iterator but that's not yet in php.net's CVS (might need some more testing, and probably we might change the design there...) so I'm emulating this with MySQLi_Result::fetch_all() combined with an ArrayIterator, using the experimental code the constructor can be dropped.
So let's finally look at the code of these two classes:
<?php
class MySQLi_ResultsetIterator implements RecursiveIterator
{
private $mysqli;
private $counter = 0;
private $current = null;
private $rewinded = false;
public function __construct(mysqli $mysqli) {
$this->mysqli = $mysqli;
}
private function freeCurrent() {
if ($this->current) {
$this->current->free();
$this->current = null;
}
}
public function rewind() {
if ($this->rewinded) {
throw new Exception("Already rewinded");
}
$this->freeCurrent();
$this->counter = 0;
$this->rewinded = true;
}
public function valid() {
$this->current = $this->mysqli->store_result();
return (bool)$this->current;
}
public function next() {
$this->freeCurrent();
$this->counter++;
$this->mysqli->next_result();
}
public function key() {
return $this->counter;
}
public function current() {
if (!$this->current) {
throw new Exception("valid() not called");
}
return $this->current;
}
public function hasChildren() {
return true;
}
public function getChildren() {
return new MySQLi_PseudoRecursiveResultIterator($this->current);
}
}
class MySQLi_PseudoRecursiveResultIterator
extends IteratorIterator
implements RecursiveIterator
{
public function __construct(MySQLi_Result $result) {
// This ctor can be dropped with the experimental bzr sources
// as IteratorIterator::__construct() directly works with
// MySQLi_Result
parent::__construct(new ArrayIterator($result->fetch_all()));
}
public function hasChildren() {
return false;
}
public function getChildren() {
throw new Exception("This should never be called");
}
}
?>
Now we can use this code. For properly using a RecursiveIterator one should use a RecursiveIteratorIterator (RII). To get some nice labels I'm extending the RII and then have a single foreach:
<?php
class MyRecursive_IteratorIterator
extends RecursiveIteratorIterator
{
public function __construct(MySQLi $mysqli, $flags = 0) {
parent::__construct(
new Mysqli_ResultSetIterator($mysqli),
$flags | RecursiveIteratorIterator::LEAVES_ONLY);
}
public function beginChildren() {
echo "Next ResultSet:\n";
}
}
$mysqli = new MySQLi("localhost", "root", "", "test");
$query = "SELECT 1,2 UNION SELECT 3, 4;".
"SELECT 'hi world' UNION SELECT 'foobar'";
if ($mysqli->multi_query($query)) {
foreach (new MyRecursive_IteratorIterator($mysqli) as $key => $row) {
printf(" %s\n", $row[0]);
}
}
?>
Now calling this code gives us a result similar to the following:
Next ResultSet:
1
3
Next ResultSet:
hi world
foobar
Isn't that nice? - I think that's a cool API! What do you think? Do you have use cases for such an API? Should we implement this in C and bundle it with PHP? Any feedback welcome!
Sometimes one has weird ideas, or am I the only one? - This specific one is at least a year old, now, during the Christmas days, waiting for New Year's Eve I had the time and mood to finally try it out: MySQL 5.1 has a plugin interface to easily add storage engines. PHP can easily embedded into other applications. So why not combine these two things? - Writing a MySQL Storage Engine which reads data by calling a PHP script.
Let's start with a simple example first:
<?phpfunction create_table($table, $data) {
return true;
}
function open_table($table) {
return new ArrayIterator(array(
array('id' => 1, 'dat' => 'foo'),
array('id' => 2, 'a' => 'bar')
));
}
?>
This is the bare minimum storage engine my plugin supports. create_table() is called for creating the table, open_table() to access it, the later one then returns an iterator which is used for a full table scan. This example uses an ArrayIterator, which implements the SeekableIterator and the Countable interfaces, the first one provides a seek() method, which is called to read specific rows after sorting for instance, the later provides a method count() which gives the optimizer a hint.
Let's use this table:
mysql> CREATE TABLE php_test (id int, val CHAR(3)) ENGINE=PHP;
Query OK, 0 rows affected (0.04 sec)
mysql> SELECT * FROM php_test;
+------+------+
| id | val |
+------+------+
| 1 | foo |
| 2 | bar |
+------+------+
2 rows in set (0.00 sec)
Ok, of course that's nice and shiny but well, it's read only. To solve that you can implement a few interfaces provided by the plugin to handle writes:
<?php
class Test extends ArrayIterator
implements MySQLStorage_Writable, MySQLStorage_Updatable, MySQLStorage_Deletable {
public function write($data) {
$this[] = $data;
}
public function update($data) {
$this[$this->key()] = $data;
}
public function delete() {
unset($this[$this->key()]);
}
}
function create_table($table, $data) {
return true;
}
function open_table($table) {
return new Test(array(
array('id' => 1, 'dat' => 'foo'),
array('id' => 2, 'a' => 'bar')
));
}
?>
Again, we can test it:
mysql> UPDATE php_test SET val = 'baz' WHERE id = 1;
Query OK, 1 row affected (0.02 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> DELETE FROM php_test WHERE id = 2;
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO php_test VALUES(3, 'bar');
Query OK, 1 row affected (0.00 sec)
mysql> SELECT * FROM php_write;
+------+------+
| id | val |
+------+------+
| 1 | baz |
| 3 | bar |
+------+------+
2 rows in set (0.00 sec)
As a reminder: This is calling PHP for all these operations.
So what might real life use cases be, once the major issues in the code are fixed? I have a few ideas like
Any other ideas? - Leave a comment ![]()
Oh, and like most MySQL stuff nowadays: There's a launchpad project for this plugin.
Over the last few days I already mentioned a few hidden gems from PHP 5.3. Now at Christmas I wanted to take a look at some new language feature of the upcoming PHP version:
Added "jump label" operator (limited "goto"). (Dmitry, Sara)
The entry is a imprecise on purpose, since it's not to be advertised too much to not be abused too much, but well, you're reading this on Christmas instead of spending time with your family, so I guess you're a geek and know already: PHP 5.3 introduces not only namespaces but also goto. Yes it's a "goto label;" the limitations i, mentioned in the NEWS entry, are: You can only jump within the same execution unit (function or global part of the same file file) and you can't jump into loops.
When you know about goto I'm sure you know it's bad, so why did we added? - Well there's a very limited set of problems where it's ok. One is generated code, a code generator using goto can be written way better than without goto and nobody is supposed to read that code anyways. The second situation is when having a longer piece of code, where situations might occur where you cancel execution sin the middle of the code but want to do some cleanup nonetheless. A short pseudo-code example:
<?php
function process_file($filename) {
$fp = fopen($filename, "r");
if (!$fp) {
goto cleanup;
}
$row = fread($fp, 1024);
// do something with the row
if ($error_while_processing) {
goto cleanup;
}
$a_few_bytes = fread($fp, 4);
// do something again ...
if ($error_while_processing) {
goto cleanup;
}
/* ... */cleanup:
fclose($fp);
}?>
There are alternatives available, like wrapping this all in loops and using break or wrap it in an try {} catch block and throw exceptions, but goto can be cleaner. So have fun and use it with care!
In the programming world there are quite a few well understood and explored data structures. Which are commonly used in tons of applications, still the only things PHP offered till 5.3 in regards to structuring data were arrays (more precise: hash tables) and objects. So people had to either abuse them for other structures or implement the structures themselves on top of these. Thanks to Etienne things now are changing and PHP's Standard PHP Library (SPL) extension will offer quite a few standard implementations of data structures. The implemented data structures are implemented using these classes:
Except for SplFixedArray the ideas behind these classes should be clear. If not you can read about them over at Wikipedia or in basically every general introduction to software programming book. For the exact naming and details of the implementation chosen for PHP you can read the fine manual. So why should you use these instead of implementing your own? - There are a few reasons the important ones are:
The only question left there might be: "Ok, that's nice and cool and I could use them, but I have to support older PHP versions for at least some time. What can I do?" - The solution there is easy as well: Most stuff in SPL doesn't do any special trick that requires an implementation in C but can also be implemented in userland. In fact most stuff is tested as userland code first to design the interfaces nicely. Others are implemented in PHP after being implemented in C as kind of documentation. These implementations are distributed with PHP source releases or via CVS, so you can simply take that code and use it.
But now let's get back to the one class which might not be clear: SplFixedArray. SplFixedArray is an implementation of a data structure similar to PHP's arrays with a big limitation: It only supports numeric indexes in a predefined range (starting at 0 and going up) like the ArrayObject from 5.2 it's class based so it can't be used with all thousands of array functions PHP offers, but within it's domain and fucntionality it's very fast and uses less memory than classic PHP arrays. so if you have a big array where numeric indexing is enough: Use it!

One of the things I do quite often is running PHP's regression test suite which is using a custom test format called .phpt. The PHP source distribution, and CVS checkouts, include a nice script for running them called run-tests.php.
run-tests.php gives a summary of failed tests in the end. As a developer I'm now interested for the reasons for the failures. The test system therefore produces a bunch of files, a file containing the expected output, one containing the actual output and a diff between these as relevant files. The problem there is that the diff, for being portable, is using a quite simple machnism which only shows the lines which differ without any context. This makes it quite hard to read. Therefore I usually diff the .exp and .out files myself for doing that I have a few simple shell scripts which I call with the test name and then get a proper diff.
Lately I've changed my way of working and use vim less, I still use it, but I use NetBeans as an IDE more and more. So I thought a bit about that test issue and searched my brain for my Java skills and started playing around to see whether I manage to write a NetBeans plugin which can run the tests and report the results in a usable way. Over the time it looked quite promising, so I registered a launchpad project and imported the code to a repository there. Now I think I've reached a true milestone which should basically work for interested folks. And released a version 0.6.0.
The module registers an menu entry and a toolbar icon to start a wizard. This wizard asks you for the PHP binaries to use and test directory to run. It will then run the tests and open a window with the results of each test. By double clicking or using a context menu you can then get the actual test code and a diff. If you have PHP support installed in NetBeans the code will also be highlighted.
There are still a few issues most importantly you need a special version of run-tests.php, which is bundled, and not all things, like redirect tests, are supported. There are certainly other issues, but the aim is mostly to help me. If you're interested feel free to report a bug and maybe I look into it. If you're brave you can also fetch the code and start hacking it - but keep in mind I'm no Java developer and had no idea what I'm aiming at and how to write NetBeans modules when I started, you can see that in the code ![]()
This code requires Java 6 (since I make use of SwingWorker) and I didn't test older NetBeans versions than 6.5 since that version has proper PHP support and there's little sense in having older versions installed.
P.S. The screenshot is a bit faked: The inner windows don't appear exactly like that, yet, but that's the aim and you can easily use Drag'n'Drop inside the IDE to arrange them till I found out how to that from within the code.
I recently wrote a few postings about great Sun stuff. The reason for that? - Well since joining Sun I get all the information about the things Sun does and there are tons of cool things, I enjoy OpenSolaris, especially DTrace and zfs (zfs snapshots!) - these are great pieces of technology. Ok, you can feel that OpenSolaris isn't finished yet, but it's a good step from a classic Unix to a quite usable system.
Now Sun is famous for another product family: Java. For me Java has always been a synonym for ugly and annoying applets and over-engineered "enterprise" applications which are close to being unusable. Being Sun I learned about a new technology for fighting the RIA wars against Microsoft's Silverlight and Adobe's Flex: JavaFX. After browsing a while over the different sites I found out that key part of JavaFX is a declarative scripting language for creating user-interfaces. That sounds quite cool - no annoying and over-verbose XML and no procedural coding for describing a GUI, but a syntax which looks quite sane for that. So I wanted to give it a shot. And that's where the trouble began ...
Ever wondered what your PHP application and MySQL actually do? An experimental mysqlnd branch will give you full access to the network communication stream. Using a custom PHP stream filter you can then intercept the communication ... but let's start at the beginning:
When talking about mysqlnd - the mysql native driver for PHP - we always mention the fact it's native in a way that we're, when possible, using PHP infrastructure. The most common example here is the memory management. By directly using PHP's memory we can avoid unnecessary copies of data from the MySQL Client Library's memory into PHP memory.
<?php
$mysqli = mysqli_connect("localhost", "root", "", "test");
$stream = mysqli_conn_to_stream($mysqli);
stream_filter_append($stream, "mysql.server", STREAM_FILTER_READ);
?>
But there's more what we're doing. We're also using PHP's stream abstraction layer. From a development perspective the benefit is that we're using a tested abstraction from different stream implementations by different operating systems instead of writing our own. But, again, there's more to it: We can export the communication stream to PHP userland. We hesitated about exporting it for some time as it can be quite dangerous and you might easily corrupt the client-server- communication.
As Ulf mentioned during his IPC talk I recently pushed a mysqlnd branch to launchpad which adds a userspace function to mysqli which returns a PHP stream for a connection. Using that stream you can now send your own requests to the server and wait for the response. That might be nice in a way, but I guess you most likely won't have use for that. PHP streams allow you to do more: PHP streams give you the possibility to add filters to a stream. These filters allow you to intercept packages which are sent or received , read them, change them or do whatever you like. A very simple filter can be found on the launchpad site, mentioned above. That filter simply prints the information after replacing unprintable (binary) characters by dots.
Once again: Just a small step, the next one is to decode the MySQL protocol. For that I've written a simple decoder for the MySQL protocol, not complete, but enough to give an idea. The script, including the decoder and some sample code using it, is, as a sample, part of the branch. When running you will get some output like
Query:
-> 0 59: QUERY: SELECT TABLE_SCHEMA FROM INFORMATION_SCHEMA.TABLES LIMIT 1
<- 1 1: DATA
<- 2 52: FIELD INFO
<- 3 5: EOF
<- 4 19: DATA
<- 5 5: EOF
Invalid Query:
-> 0 29: QUERY: ghdfjtgfdrs tztr ttgdszthtdr
<- 1 183: ERROR: 2000You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'ghdfjtgfdrs tztr ttgdszthtdr' at line 1
Prepare:
-> 0 61: PREPARE: SELECT TABLE_NAME FROM INFORMATION_SCHEMA.STATISTICS LIMIT 2
<- 1 12: OK
<- 2 52: FIELD INFO
<- 3 5: EOF
Ping:
-> 0 1: PING
<- 1 7: OK
Execute:
-> 0 11: EXECUTE
<- 1 1: DATA
<- 2 52: FIELD INFO
<- 3 5: EOF
<- 4 15: OK
<- 5 15: OK
<- 6 5: EOF
EOF
-> 0 5: CLOSE_STMT
-> 0 1: QUIT
As one can see: The protocol isn't fully decoded yet so this all might be extended but for me it served the purpose well enough. For making real use out of this we're thinking about exporting the protocol decoder which exists within mysqlnd to PHP userland.
What are your ideas for such a feature? - Sending different queries to different servers? Rewriting queries? Sharding? Replication? Easy scaling of your application while refactoring your application? Let us know!
Angelo recently showed an easy way to dump SQL queries using DTrace, while reading the articles I felt that some important information is missing: The name of the user executing the query and the selected database. So I sat down a few minutes and tried to collect that data.
For the database name I found a quite simple solution: It is passed as parameter to the check_user() function to MySQL so we can easily add a thread-local variable to keep that name. Simple script for that:
#!/usr/sbin/dtrace -s
#pragma D option quiet
pid$1::*check_user*:entry
{
self->db = arg4 ? copyinstr(arg4) : "(no schema)";
}
pid$1::*dispatch_command*:entry
{
printf("%s: %s\n", self->db, copyinstr(arg2));
}
Getting the username is a bit harder, for the PID-provider we need a function where it is passed as parameter, best would be if it was passed as char*, but there's no such function reliably called. (For instance there are functions for checking max connections per user where all we need is passed in a proper way, but it's only called when a limit was set) The only way would be to take the user_connect property of the THD object which is passed to dispatch_command and then access the username (and hostname). But getting that working from within DTrace is quite some work. I prepared some scripts doing this with simple C structures for the second part of my DTrace article series, which is ready in my head and is waiting to be typed, so in theory it should be possible, anybody wants to try?
The best solution, of course, would be to add proper probes into the MySQL server code which provide all that information.
Over the past few weeks I annoyed my environment with praising DTrace whenever possible. Yesterday, during a break at the Barcamp Munich, I gave Wolfram a short introduction on his Mac and decided to put some stuff here:
DTrace is a toolkit available on Solaris (Solaris 10 or OpenSolaris), recent MacOS versions and FreeBSD for mightier than tools like truss or strace but with way less impact. DTrace allows you to "hook" (called "probes") into the system and allows to do some analysis then.
I guess all that works best by showing an example first: PHP uses a wrapper over the system's memory allocation using a function called _emalloc (which is wrapped by a CPP macro called emalloc) so it might be interesting to see how often that function is being called. For doing that we can use a D-script (D being the DTrace scripting language, not DigitalMars's D) like that:
#!/usr/sbin/dtrace -s
#pragma D option quiet
pid$target::_emalloc:entry
{
printf("_emalloc was called!\n");
}
We can now simply call that script and tell DTrace to start a PHP interpreter and run a PHP script. DTrace will then change the running program in memory so that the message is printed whenever the system for the process, with the PID $target, enters the function _emalloc. $target is a special variable referring to a process started by DTrace using -c or a PID provided using -p.
$ ./script1.d -c "php script.php" _emalloc was called! _emalloc was called! _emalloc was called! ...
That's nice but not really useful in any way, yet. As we'd like to at least know the size of the allocated memory area, which is the first parameter to _emalloc. The pid-provider helps us by providing the parameters to the functions as D-variables, so we can simply change our action to print that variable:
printf("_emalloc called, allocating %i bytes\n", arg0);
running the script now gives us the sizes:
./script2.d -c "php script.php" _emalloc was called, allocating 5 bytes _emalloc was called, allocating 6 bytes _emalloc was called, allocating 5 bytes ...
The output is quite long and still rather useless, for making use from this information we at least need some aggregation, but DTrace helps there, too, so let's create an aggregation variable collecting the data in a usable way:
#!/usr/sbin/dtrace -s
#pragma D option quiet
pid$target::_emalloc:entry
{
@mallocsize["emalloc"] = quantize(arg0);
}
mallocsize and emalloc are there freely chosen identifiers. Depending on your script the output now looks something like the following:
emalloc
value ------------- Distribution ------------- count
0 | 0
1 | 83
2 |@@ 1122
4 |@@@@@@@@ 5141
8 |@@@@@@ 4032
16 |@@@@@@@@@@@@@@@@@@ 11881
32 |@@@@@@ 3694
64 |@ 806
128 | 27
256 | 66
512 | 1
1024 | 1
2048 | 1
4096 | 1
8192 | 4
16384 | 0
32768 | 1
65536 | 0
131072 | 1
262144 | 0
This tells us that the most used allocation size is between 9 and 16 bytes and the largest space allocated is somewhere between 65536 and 131072 bytes.
For a deeper analysis we can now add a predicate to our probe so the action triggers only for that allocation. Such predicates are writing between slashes between the probe name and the action. Additionally I'm adding a ustack() call to the action, this will print the systems userspace backtrace -- which is C level, not PHP space.
#!/usr/sbin/dtrace -s
#pragma D option quiet
pid$target::_emalloc:entry
/ arg0 > 131072 /
{
printf("_emalloc(%i)\n", arg0);
ustack();
}
$ ./script4.d -c "php script.php"
emalloc(261900)
php`_emalloc
php`zend_vm_stack_new_page+0x19
php`zend_vm_stack_init+0xf
php`init_executor+0xf5
php`zend_activate+0x12
php`php_request_startup+0x7a
php`main+0xd86
php`_start+0x7d
So we see we're in the startup of PHP allocating some space on it's stack. One question now might be about the costs of an _emalloc call, one important factor there are syscalls to the operating system. As DTrace is made for utilizing the whole system that can be done quite easy using the syscall provider. Me might now use syscall:::entry as probe to be triggered on every call, but that will be quite a lot. As we're only interested in syscalls from _emalloc we'll use a thread-local variable as a flag and check that flag in the predicate condition:
#!/usr/sbin/dtrace -s
#pragma D option quiet
pid$target::_emalloc:entry
/ arg0 > 131072 /
{
self->inemalloc = 1;
}
pid$target::_emalloc:return
/ arg0 > 131072 /
{
self->inemalloc = 0;
}
syscall:::entry
/ self->inemalloc /
{
printf("%s", probefunc);
}
$ ./script4.d -c "php script.php" brk brk
So we're calling brk two times. brk is the syscall to "change the amount of space allocated for the calling process's data segment" which is exactly what we expect, but why is it called two times? Adding a ustack call to the syscall action can tell us where it happens, using the source this can then probably be optimized. That's left as an exercise to the interested reader.
In summary: No need to change the code and lots of information, I plan to write an additional article showing how to get interesting facts system-wide, not only for a specific process but all running ones, which is especially interesting when searching for a problem on production systems (DTrace is made to be used on productive systems!) or problems related to concurrent processes/threads.
DTrace is a damn cool debugging tool, unfortunately only available for Solaris and different BSD flavors. If you want to learn about it watch the quite entertaining video (well, I guess you should be a true geek to be entertained, ...) from Bryan Cantrill's talk.
The reason for me writing this is that I had some problems with the PID provider and wanted to note the solution for myself:
$ dtrace -n 'pid1005:::entry { printf("Hello"); }'
probe description pid1005:::entry does not match any probes
The reason is that my user only had the dtrace_user, not the dtrace_proc right. Setting the attributes correctly solved the issue. Time for more DTrace'ing.
As most of you might have seen we recently announced the first alpha of PHP 5.3.0. The major changes are listed in the announcement. Source tarballs can be found on PHP's downloads site, as it's the first release I packaged I'm especially interested in feedback, whether it works or not
. But we didn't only have changes on the source builds: A new team took over the creation of Windows builds. As they also did a major update to the Windows build architecture (supporting newer compiler versions on Windows and added experimental support for 64bit platforms) the build process got a bit delayed but builds should be available soon.
Remember: It's a release we packaged to get feedback from our users. So please test it. If you find issues please report them - the sooner we know about issues the sooner they can be addressed. Although our test coverage increased we can't cover all cases in our tests so please test it now and don't wait for the stable release, once the stable release is out your edge case might trigger a bug on a productive system, bugs reported now can be fixed before we release a final version.
If you want to give back to the PHP project - hey you probably make a living out of software you get for free - and can't fix bugs or assist in a similar way you probably could help our documentation team with improving the documentation, there are a few features without proper documentation, yet.
As others already wrote PHP participates in this year's Google Summer of Code program. If you are a student we'd welcome your application!
Some general hints: