I would like to use GDB to step though the C++ code that makes up the php.so Apache extension. I want to see what PHP is doing while it's running a PHP application. Preferably I would use an IDE like Netbeans or Eclipse on a LAMP system.
You want to get your hands on a debug build of mod_php (with symbols) or build your own (configure --enable-debug)
You should configure your Apache to always keep exactly one worker process instance up (which will be the instance you debug), that is, set MinSpareServers, MaxSpareServers and StartServers all to 1. Also make sure any timeout parameters are generously set
Use gdb or any graphical interface to gdb (such as ddd or Eclipse CDT) to attach to the one and only Apache worker process. Stick a breakpoint in one of the PHP sources etc. and continue.
Point your browser to your webserver and access a PHP page. Your breakpoint will trigger. If you want to wake the debugger at a particular point in your PHP script execution, generate a SIGTRAP from PHP and gdb will normally oblige you.
Have fun!
Maybe you could do that on windows.
However, your best bet is to do this on a Unix box. You will have to compile everything with debugging enabled. GDB will need access to those directories for source.
Then you will have to run apache and then run the process.
In order to give yourself time to attache while you are hitting the PHP/Apache with a browser, add a sleep call in the PHP script. If you ps, you will see the process in the sleep state. Or you could just have it write its process id to a file in tmp before it does the sleep.
Related
I have an XML database that I want to manage independently from users on my website. Looking into the matter it appears that I should write a daemon script to manage my database. That is all fine and dandy but, I feel like I'm opening a can of worms. I wanted to write my daemon script in PHP, so I looked into PCNTL. But I quickly learned that PCNTL is not suited for web servers. So now I am stumped. How can I get a daemon to run on my server? Do I need to learn another language? I only want to write my own scripts. But I feel lost. I would prefer to write my daemon in PHP as I am familiar with the language.
I have been researching everything from PCNTL, CLI, SO questions, numerous articles on daemon processes... etc
I am running PHP 5.6.32 (cli), windows 7, on Apache. XAMPP 5.6.32. Unix system.
EDIT: I also have windows setup to run PHP from command prompt.
There's nothing wrong in running a PHP daemon, however it's not the fastest thing, especially before the 7.0 version. You can proceed in two ways:
Using Cron Jobs, if you're under Unix systems crontab will be fine, in this way you can specify the interval within the system automatically executes the specified script and then exit.
The true daemon, firstly you need to change the max_execution_time in PHP.ini to 0 (infinite), then in your daemon call for first function set_time_limit(0);, remember to run it only once. However if there is some failure like a thrown error uncatched the script will exit and you need to open it again manually, and don't try...catch in a while loop because it will probably go into an endless loop. Execute the script with php -f daemon.php.
I want to know what functions are being called and what time each request is taking for an application which is running on apache.
Is there any tool or any other way where i can get this data.
I also want to know how much time each function is taking.
The application is running it cannot be stopped.
So i need to get the details in the running environment itself.
Thanks in advance.
One of the most used industry tools for this is: http://www.xdebug.org/
I have used it religiously for a long time now! From it's front-page it does the following:
"The Xdebug extension helps you debugging your script by providing a lot of valuable debug information. The debug information that Xdebug can provide includes the following:
* stack traces and function traces in error messages with:
o full parameter display for user defined functions
o function name, file name and line indications
o support for member functions
* memory allocation
* protection for infinite recursions"
Xdebug can write a profiling file that you can analyze in kcachegrind or wincachegrind.
It depends on whether you want active or passive profiling.
Passive tools such as New Relic work silently in the background and collect a little information about all requests by sacrificing a small amount of compute resources. These generally have more information regarding the entire server stack. These are typically used for production environments, which sounds like what you require.
Active profilers are used for development and will run just once per request, collecting a lot of information specifically about the part of the application you are working on at the cost of a large performance hit. The most common PHP active profiler is probably Xdebug.
Ways to analyse the data from Xdebug:
NOTE: If you use a virtual machine, vagrant, docker etc make sure you set the output dir to a shared volume, accessible outside of the virtual machine
e.g.
(php.ini) xdebug.profiler_output_dir = "/project_root/tmp"
If you use PHPStorm:
Tools > Analyse Xdebug Profiler snapshot...
For those using Xdebug on MacOS:
Using homebrew install qcachegrind and AppViz
brew install qcachegrind
brew install graphviz
Then run it from command line:
qcachegrind cachegrind.out.1394
OR just run qcachegrind and open the cachegrind file generated by xdebug using the GUI navigator
There are couple of PHP profiling tools,
such as
xdebug
Particletree
I installed xdebug on my Apache and if I define a breakpoint in Netbeans, the execution breaks fine. But if I execute the tests with symfony phpunit:test-all, the execution will not break on the given break point.
Any ideas?
cowabunga!
To debug a command-line script, export the XDEBUG_CONFIG variable first, like so:
export XDEBUG_CONFIG="idekey=netbeans-xdebug" (Unix/Linux/OS X)
set XDEBUG_CONFIG=idekey=netbeans-xdebug (Windows)
(Note: I did not test the Windows command. You may have to escape the = character, or the command may look a bit different. If that's the case, I hope someone comes along and corrects me in a comment.)
Explanation: When you open a debugging session for a script that runs through Apache, NetBeans will open your browser to a URL that ends with "XDEBUG_SESSION_START=netbeans-xdebug". When this happens, Xdebug knows to intercept this argument and give your browser a cookie with this debug session information.
The command above is the equivalent for setting the cookie in the command line environment.
When you say you define a breakpoint in Netbeans and it breaks fine, are you talking about running the unit tests from within Netbeans, or running a web application that triggers the breakpoints in Netbeans?
Either way, my first guess would be that the two scenarios are using different PHP.INI files. Get one of your unit tests to dump configuration information and you'll see pretty quickly I daresay. Find the PHP.INI that's being used on the command line and make sure that XDebug is set up for that scenario.
I hope that makes sense. I'm entirely coffee-free at the moment.
I don't use netbeans but I don't think netbeans modifies the file you put break points in and I don't think that symfony can read your netbean configuration to find out where to break.
Also if you are running the test all task inside netbeans and expect the test files to break I don't think that will work either as the task forks php processes I believe and these processes won't be readable by netbeans.
All hypothesis of course.
In python, one can trace all the statements that are executed by a command line script using the trace module. In bash you can do the same with set -x. We have a PHP script that we're running from the command line, like a normal bash / python / perl / etc script. Nothing web-y is going on.
Is there anyway to get a trace of all the lines of code that are being executes?
There is a PECL extension, apd, that will generate a trace file.
Not in pure-PHP, no -- as far as i know.
But you can use a debugger ; a nice way to do that is with
The extension Xdebug, which can be used as a debugger
and some graphical IDE that integrates some debugging tools, like Eclipse PDT
Both of those are free, btw.
With those, you can do step by step, set up breakpoints, watch the content of variables, view stack traces, ... And it works both for Web and CLI scripts ;-)
Of course, it means having Eclipse running on the machine you are executing your script... But if you are executing it on your development machine, you probably have a GUI and all that, so it should be fine...
(I know that, for web applications, you can have Eclipse running on a different machine than the one with the PHP webserver -- don't know if it's possible in CLI, though)
As a sidenote : maybe you can integrate Xdebug with a CLI-based debugger ; see the page I linked to earlier for a list of supported tools.
I'm kinda blind here but I guess one way you could do it is to write all the relevant code inside custom functions and call debug_backtrace(). debug_print_backtrace may also be useful.
I hope it helps.
Has anyone been able to get xinc to run correctly under OpenBSD's chrooted default Apache? I'd like to keep our development server running fully chrooted just like our Production server so that we make sure our code runs just fine chrooted.
Have you posted the issue on the Xinc bug tracker? Xinc itself should run fine as it runs both as a daemon and as a web app. As you alluded to, the issue may be that the daemon is not running in a chroot'ed environment where as the web interface is, leading to either side not grabbing the files.
#dragonmantank
In Xinc's case, I hope you used PEAR to install it.
pear list-files xinc/Xinc
This should do it, and show you where your Xinc install put its files. So even though Xinc is "just" one big PHP script, it's still spread out into rc scripts and all those other things which are necessary to make an application run. I'm sure you don't need to add all paths listed there, but probably some in order to make it run.
Aside from Xinc itself, I think it also needs phpUnit and a bunch of other PEAR libs to run, so what I'd propose is this:
pear config-get php_dir
And then you need to add that path (like Henrik suggested) to the chroot environment.
Having never used xinc myself, I can only hint as to how I usually get to chrooting apps.
First step would be to gather information on everything the app needs to run; this I usually accomplish by running systrace(1) and ldd(1) to find out what is needed to run the software.
Go through the output of
systrace -A -d. <app>
ldd <app>
and make sure that everything the app touches and needs (quite a lot of apps touch stuff it doesn't actually need) is available in the chroot environment. You might need to tweak configs and environment variables a bit. Also, if there is an option to have the app log to syslog, I usually do that and create a syslog socket (see the -a option of syslogd(8)) in order to decrease the places the app needs write access to.
What I just described is a generic way to make just about any program run in a chroot environment (however, if you need to import half the userland and some suid commands, you might want to just not do chroot :). For apps running under Apache (I'm sure you're aware that the OpenBSD httpd(8) is slightly different) you have the option (once the program has started; any dynamic libraries still needs to be present in the jail) of using apache to access the files, allowing the use of httpd.conf to import resources in the chroot environment without actually copying them.
Also useful (if slightly outdated) is this link, outlining some gotchas in chrooted PHP on OpenBSD.
First step would be to gather information on everything the app needs to run; this I usually accomplish by running systrace(1) and ldd(1) to find out what is needed to run the software.
I'll give this a try. The big issue I've found with xinc is that while it is a PHP application, it wants to know application installation paths (yet it still spreads stuff into other folders) and runs some PHP scripts in daemon mode (those scripts being the hardest to get running). So, for example, I told it to install to /var/www/xinc and then made a symlink of
/var/www/var/www/xinc -> /var/www/xinc
and it partially worked. I got the GUI to come up bit it refused to recognize any projects that I had set up. I think the biggest problem is that part of it is running a chroot and the other half is running outside.
If all else fails I'm going to just have to build something as we program inside chrooted environments since our production is chrooted. We've run into issues where we code outside of a chroot and then have to back track to find what we need to make it work inside a chroot.