I'm compiling the linux source code on a different machine to where I will be testing this (I'm trying to see if I can trace if/where a commit that is causing some weird behaviour on my machine), and I therefore want to try to build packages which I can install on the test machine.
The test machine runs Fedora, so, therefore, I would use make binpkg-rpm to generate those packages.
The output I get is two rpms -- one for the kernel and one for the headers. All good.
Some things I noticed at this point, however:
The kernel rpm is HUGE -- like 1G+ in size.
The kernel-headers package obsoletes kernel-headers (and the rpm generation actually warns of this). Removing this package after installation makes Fedora want to remove a TON of other packages.
There are no separate module packages (e.g. kernel-modules, kernel-modules-extra)
So a few questions I have regarding the compilation process (and I cannot find any documentation on the web to answer these)
Why is the generated kernel rpm so big?
Why are there no separate modules rpms? Is there a switch I need to use to generate these?
Why does the kernel-headers generation throw that obsoletes message and why does removing it make Fedora want to remove so many other packages?
I did use the kernel config of the current running kernel (i.e. I copied the config from the /boot folder and renamed it .config)
Many thanks in advance for any guidance, even if it's just pointing me to a page which answers my questions (that my hours of searching didn't uncover)
I'm working on a HTTP/1.1 server in C as a learning experience and want to make it performant while still being dynamic. Performing a get or post on static files or scripts was easy enough, but I'd like to add the ability to call compiled binaries for greater speed.
Currently, I link these compiled binaries directly into the server binary, but I'd like to be able to update and hot swap them. I considered dynamically linking them as shared libraries, but I don't want to relink them to handle every request. I also considered creating a new process to run them, however that incurs significant overhead every request and makes getting the response back to the client difficult (I'm using OpenSSL sockets).
How could I efficiently relink these compiled binaries when they update, without shutting down the server?
I'm testing on Debian Sid and running on an AWS ECS instance with CentOS 7. Both have Linux kernel versions 4.19+
I'd like to be able to update and hot swap them. I considered dynamically linking them as shared libraries
You appear to believe that you can update a shared library (on disk) that a running server binary is currently using, and expect that running server process to start using the updated library.
That is not how shared libraries work. If you try that, your server process will either crash, or continue using the old library (depending on exactly how you update the library on disk).
This can be made to work in limited circumstances if you use dlopen to load the library, and if you can quiesce your server, and have it dlclose to unload the previously loaded version, and then dlopen updated version. But the exact details of making this work are quite tricky.
We work on scientific computing and regularly submit calculations to different computing clusters. For that we connect using linux shell and submitting jobs through SGE, Slurm, etc (it depends on the cluster). Our codes are composed of python and bash scripts and several binaries. Some of them depend on external libraries such as matplotlib. When we start to use a new cluster, it is a nightmare since we need to tell the admins all the libraries we need, and sometimes they can not install all of them, or they only have old versions that can not be upgraded. So we wonder what could we do here. I was wondering if we could somehow "pack" all libraries we need along with our codes. Do you think it is possible? Otherwise, how could we move to new clusters without the need for admins to install anything?
The key is to compile all the code you need by yourself, using the compiler/library/MPI toolchains installed by the admins of the clusters, so that
your software is compiled properly for the cluster hardware, and
you do not depend on the admin to install the software.
The following are very useful in this case:
Ansible, to upload/manage configuration files, rc files, set permissions, compile your binaries, etc. and deploy a new environment easily on new clusters
Easybuild to install your version of Python with all the needed dependencies, and install other scientific software thanks to the community supported build procedures
CDE to build a package with all dependencies for your binaries on your laptop and use it as-is on the clusters.
More specifically for Python, you can use
virtual envs to setup a consistent set of Python modules across all clusters, independently from the modules already installed; or
Anaconda or Canopy to use a Python scientific distribution
to have a consistent Python install across all clusters.
Don't get me wrong, but I think what you have to do so: stop behaving like amateurs.
Meaning: the integrity of your "system configuration" is one of the core assets of your "business". And you just told us that you are basically unable of easily re-producing your system configuration.
So, the real answer here can't be a recommendation to use this or that technology. The real answer is: you, and the other teams involved in running your operations need to come together and define a serious strategy how to fix this.
Maybe you then decide that the way to go is that your development team provides Docker buildfiles, so that your operations team can easily create images on new machines. Or you decide that you need to use something like ansible to enable centralized control over your complete environment.
That's what venv is for, it allows you to create a portable customized environment easily, with exactly what you need and nothing more.
I completely agree with https://stackoverflow.com/users/1531124/ghostcat
but here is the really bad answer that will cause you a lot of problems in near future!!!:
if you need some dynamic library and you are not planning to upgrade them in future, you can try copying all needed libs to a folder in your app and use an script to launch the app:
#!/bin/sh
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/path/to/your/lib/folder
./myAPP
but keep in mind that this is bad practice.
Create a chroot image, like here - click. Install everything you need and then you can just chroot into it on any machine.
I work on scientific clusters as well, and you are going to find that wherever you go.
I would only rely on the admins on installing the most basic stuff. That is:
- Software necessary to build your software or run the most basic stuff: compilers and most basic utilities (python, perl, binutils, autotools, cmake, etc.).
Software libraries that make use of I/O devices: MPI, file I/O libraries...
A queue system (they already have it most of the time).
Environment modules. This is not a must, but it really helps you get the job done, specially if you mess with different library versions or implementations (that's my case, for example).
From that point on, you can build and install on your own directories all the software you use most of the time.
This does not mean that you cannot ask an admin to install some libraries. If you feel that many people is going to benefit from that, then you should request its installation. In addition, you may need some specific version or some special features which are not used most of the time, but you really need them. A very good example is with BLAS libraries (basic lineal algebra subroutines):
You have lots of BLAS implementations available: the original BLAS, Intel MKL, OpenBLAS, ATLAS, cuBLAS
If that is not enough, the open source versions usually offer multiple configuration options: serial version, parallel version with PThreads, parallel version with OpenMP, parallel version with MPI...
In my particular case, most of the software that I felt was necessary for many users in the cluster ended up being installed by the admins without any problem (either me or other users requested it), but you also have to keep in mind that in a cluster there can be many users and a single person/team is not able to attend the specific requirements you need, specially if you are able to do so.
I think you want to containerize your application in some way. Two main options (because docker/rkt and similar things are way too heavyweight for your task if I understand it correctly) in my opinion are runc and snappy.
Runc relies on OCI runtime specification, you need to create an environment (that is very similar to chroot environment in that you need to copy everything you software uses in one directory) and then you'll be able to run your application with runc tool. Runc itself is just one binary, at the moment it requires root privileges to run (hello, cluster admins), but there are patches at least partly solving that, so if you build your own runc and there are no blocking things wrt root privilege requirements you may be able to run your application with no administration overhead at all.
Snappy is similar in that you need to prepare a snap package for your application, this time using snapcraft as an assistant tool. Snappy is probably a bit easier in creating an application image and IMO is certainly better for long-term support because it clearly separates your application from the data (kinda W^X, application image is a read-only squashfs file and application can only write to a limited set of directories). But at the moment it will require your cluster admins to install snapd and to perform some operations like snap installation that require root privileges. Still, it should be better than your current situation, because that's just one non-intrusive package to install.
If these tools don't fit for some reason, there is always an option to make something of your own. That won't be easy and there are many subtle details that can bite you when doing that, but it can be done, compile all of your dependencies and applications into some path, create wrapper scripts to set up PATH and LD_LIBRARY_PATH environment for your components and then bring that directory into the new cluster, run wrapper scripts instead of target binaries and that's it. It's similar to what XAMPP does, they have quite a number of integrated things packaged into one directory that works across many distributions.
update
Let's also add AppImage into the mix, theoretically it can be a savior for your case, as it specifically does not require root privileges. It's kinda inbetween Snappy and rolling your own, as you need to prepare your application directory yourself (snappy can manage some of dependencies with snapcraft when you just specify "I need this Ubuntu package"), add appropriate metadata and then it can be packaged into single executable.
For our Travis-CI builds of the Jailhouse hypervisor, we have a rather costly environment setup which consists of a partial distribution update to pull in a recent make version (>=3.82, the default one is still only 3.81 - Ubuntu...), a cross toolchain for ARM and a 100 MB package of prebuilt Linux kernel sources that we need to compile an out-of-tree module.
To reduce the build time and the number of kernel downloads, we currently build all configuration variants sequentially in a single run (make; make clean; make...). That was fine for checking for build breakages, but with the addition of a Coverity scan, which depends on the build outputs, it no longer works. Switching to a build matrix seems the obvious solution, at the price of multiple installations because Travis-CI seems to be unable to reuse them during such builds. While we currently only have 3 configuration variants, this will increase in the future (e.g. every ARM board added will increase it by one), thus the approach does not really scale.
Do we have any alternatives? I already looked at caching, available via the docker-based build, but lacking sudo support there prevents this approach. Other ideas?
You should change your build to do this
cov-build --idir <target1> make; make clean
...
Use different intermediate directories for each build. Then go back later and run
cov-analyze --idir <target1>
cov-commit-defects --idir <target1> --stream <target1>
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 11 months ago.
The community reviewed whether to reopen this question 11 months ago and left it closed:
Original close reason(s) were not resolved
Improve this question
If I use gcore to make a code dump of a Node.js process, what are the best tools to analyze it?
Inspired by:
Tool for analyzing java core dump
In my specific case, I'm interested in investigating some memory leaks, so I'm really curious to get some heap analysis. General tools and even instrumentation packages and techniques are also welcome. I'm finding Node.js to be very interesting, but the runtime analysis tools are just not there yet.
For investigating crashes, I've found node-segfault-handler to be invaluable. It's a module I cooked up to get a native-code stack trace in the event of a hard-crash with a signal - eg deref of NULL leading to SIGSEGV
For investigating memory / allocation issues, here's some of the data I've collected thus far:
1) Blog post by Dave Patheco - the author talks about using a plugin to MDB for getting JS stacks and such. Sadly, as far as I can tell, the source of that plugin was never released (nor any binary form).
2) Postmortem Debugging in Dynamic Environments - ACM Queue article also written by Dave Patheco (linked from the blog post). While it makes for GREAT background reading, the article doesn't have many concrete tools and techniques in it.
3) node-panic - A pure-JS tool for dumping state in the event of an assert-failure type crash. Does nothing to help debug crashes that originate from native code faults (SIGSEGV, etc)
4) Joyent: Debugging Production Systems - talk by Bryan Cantrill on the tools and techniques he recommends (thx crickeys).
On Linux and Mac you can use llnode a plugin for the lldb debugger. The project is available under the nodejs organization on github:
https://github.com/nodejs/llnode
You can install from source via github or use brew on Mac. The readme on github should help you get it installed and there's an introductory blog article here:
https://developer.ibm.com/node/2016/08/15/exploring-node-js-core-dumps-using-the-llnode-plugin-for-lldb/
The original question was about memory analysis and the v8 findjsobjects and v8 findjsinstances commands will help there by generating a basic histogram of object counts and allowing you to list the instances of each type.
There's a full article on using llnode for memory analysis here:
http://www.brendangregg.com/blog/2016-07-13/llnode-nodejs-memory-leak-analysis.html
2017 update: Now you can use #h-hellyer's solution (llnode, based on lldb rather than mdb). https://stackoverflow.com/a/40045103/3221630
mdb + mdb_v8 is the way to go.
In order to use mdb, you will need a supported OS.
Now, most likely you will be running on Linux. If this is your case:
Part 1. get your core dump
You can get your core dump in many ways.
To get your core dump from a running process you can do this:
pgrep -lf node # get pids
gdb -p your_pid
# once in gdb..
gcore # this will output your core dump
detach # this will allow the process to continue to run.
Part 2. use mdb
There is a chance you know about Solaris, OpenSolaris, IllumOS or SmartOS. Most likely this is not the case. If you can afford the time of setting up SmartOS and mdb_v8, fine.
If not, install VirtualBox, and then autopsy. This handles the ritual of installing SmartOS as well as uploading your core dump files to the VM.
Once you are done, and when you are in your mdb session, you can then follow some of the steps from this presentation.