I have been using the flamegraph profiler, rs-flamegraph, quite successfully over the past few days. When I run it from bash it works fine. No sudo or anything.
~/.cargo/bin/flamegraph -o "$f flamegraph.svg" ./binary
When I invoke the binary from Rust using process::Command it fails saying that it cannot sample collapsed stack.
let svgfilename = format!("{} flamegraph.svg", path);
let execution = std::process::Command::new("/home/arkadiusz/.cargo/bin/flamegraph")
.arg("-o").arg(&svgfilename)
.arg("./binary").arg("solve").arg("real-data").arg("/dev/null")
.output().unwrap();
Full error:
WARNING: Kernel address maps (/proc/{kallsyms,modules}) are restricted,
check /proc/sys/kernel/kptr_restrict and /proc/sys/kernel/perf_event_paranoid.
Samples in kernel functions may not be resolved if a suitable vmlinux
file is not found in the buildid cache or in the vmlinux path.
Samples in kernel modules won't be resolved at all.
If some relocation was applied (e.g. kexec) symbols may be misresolved
even with a suitable vmlinux or kallsyms file.
Couldn't record kernel reference relocation symbol
Symbol resolution may be skewed if relocation was used (e.g. kexec).
Check /proc/kallsyms permission or run as root.
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0,000 MB (null) ]
thread 'main' panicked at 'unable to generate a flamegraph from the collapsed stack data: Io(Custom { kind: InvalidData, error: "No stack counts found" })', /home/arkadiusz/.cargo/registry/src/github.com-1ecc6299db9ec823/flamegraph-0.4.0/src/lib.rs:315:6
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Linux kernel version: 4.18.0-17
I am porting some 4.15 kernel customizations to 4.18, but my 4.18 kernel does not boot. A stock 4.18 kernel (i.e. the starting point before merging the 4.15 modifications) boots and runs.
The error message is:
Failed to execute /init (error -7)
Starting init: /bin/sh exists but couldn't execute it (error -7)
"errno 7" is "E2BIG 7 Argument list too long"
What does that mean in the context of the kernel starting the init process?
If the kernel command line and root file systems is exactly the same as the one you are giving to the kernel version that does boot than the most likely cause is that get_user_pages_remote() is failing here: https://elixir.bootlin.com/linux/v4.18/source/fs/exec.c#L194
Which would imply one of your changes broke memory management.
To get here, just track from try_to_run_init_process() which runs init to all the functions called from it which can return E2BIG. This is the only call site that does not depend on init argument list or environment size - https://elixir.bootlin.com/linux/v4.18/source/init/main.c#L1001
Having said that, I would first make VERY sure that the kernel command line and root file system are the same.
I'm working on a bsp layer for SBC Pine64 and my image is successfully generated but I'm getting "FATAL: kernel too old" when booting init
from busybox. I've checked my busybox binary and it's being compiled for kernel 3.14.0.
My kernel is version 3.10 and I've used Linaro 5.3 toolchain. I've tried adding: OLDEST_KERNEL = "3.10.0" and I've also tried using Linaro 4.9 but I
still get the same error. I'm using yocto Krogoth and generating core-image-minial. Please, see below a snip of the error from boot log:
[13.068932] EXT4-fs (mmcblk0p2): couldn't mount as ext3 due to feature incompatibilities
[13.086717] EXT4-fs (mmcblk0p2): couldn't mount as ext2 due to feature incompatibilities
[13.112988] EXT4-fs (mmcblk0p2): mounted filesystem with ordered data mode. Opts: (null)
[13.127040] VFS: Mounted root (ext4 filesystem) readonly on device 179:2.
[13.143393] devtmpfs: mounted
[13.151972] Freeing unused kernel memory: 520K (ffffffc0009e4000 - ffffffc000a66000)
FATAL: kernel too old
[13.198566] Kernel panic - not syncing: Attempted to kill init! exitcode=0x00007f00
[13.198566]
[13.218884] CPU: 2 PID: 1 Comm: init Not tainted 3.10.102-pine64 #1
[13.230876] Call trace:
How can I configure yocto to compile linaro eglibc for kernel 3.10.0?
Thx,
Montez
When you want to override an existing variable that is not "soft-assigned", which is to say does not use the ?= syntax but instead = syntax, you need to use one of the variables in OVERRIDES as part of changing the value. You can see how overrides work already as in conf/bitbake.conf we have:
##################################################################
# Kernel info.
##################################################################
OLDEST_KERNEL = "3.2.0"
OLDEST_KERNEL_aarch64 = "3.14"
OLDEST_KERNEL_nios2 = "3.19"
And aarch64 is already found in your overrides list. Fortunately there are other values in that list, and when evaluating variables the ones later in the list in OVERRIDES take precedence. So in your local.conf you can do:
OLDEST_KERNEL_forcevariable = "3.10"
And then confirm that it has taken effect:
$ bitbake -e busybox | grep -E ^OLDEST_KERNEL=
OLDEST_KERNEL="3.10"
I'm getting the error "cannot reserve arena virtual address space" while compiling golang on OpenBSD with command "ksh all.bash" (also tried make.bash but didn't work). This is the output:
$ ksh all.bash
# Building C bootstrap tool.
cmd/dist
# Building compilers and Go bootstrap tool for host, openbsd/386.
lib9
libbio
... (truncated)
pkg/go/doc
pkg/go/build
cmd/go
throw: runtime: cannot reserve arena virtual address space
I tried following the directions on http://code.google.com/p/go-wiki/wiki/OpenBSD, but it is also possible I didn't do it correctly. Any tips would be greatly appreciated.
Seems like rather than screwing with the "staff" group, changing the defaults for the "default" section solved the issue.
default:\
:path=/usr/bin /bin /usr/sbin /sbin /usr/X11R6/bin /usr/local/bin /usr/local/sbin:\
:umask=022:\
:datasize-max=infinity:\
:datasize-cur=infinity:\
:maxproc-max=256:\
:maxproc-cur=128:\
:openfiles-cur=128:\
:stacksize-cur=4M:\
:localcipher=blowfish,6:\
:ypcipher=old:\
:tc=auth-defaults:\
:tc=auth-ftp-defaults:
Your program fails to allocate virtual address space
http://code.google.com/p/go/source/browse/src/pkg/runtime/malloc.goc#374
I do not use OpenBSD myself, and do not know what your problem is. But you could try and gather more information yourself, if you insert some printouts here:
http://code.google.com/p/go/source/browse/src/pkg/runtime/mem_openbsd.c#54
Alex
I'm compiling a custom kernel under Ubuntu and I'm running into the problem that my kernel doesn't seem to know where to look for firmware. Under Ubuntu 8.04, firmware is tied to kernel version the same way driver modules are. For example, kernel 2.6.24-24-generic stores its kernel modules in:
/lib/modules/2.6.24-24-generic
and its firmware in:
/lib/firmware/2.6.24-24-generic
When I compile the 2.6.24-24-generic Ubuntu kernel according the "Alternate Build Method: The Old-Fashioned Debian Way" I get the appropriate modules directory and all my devices work except those requiring firmware such as my Intel wireless card (ipw2200 module).
The kernel log shows for example that when ipw2200 tries to load the firmware the kernel subsystem controlling the loading of firmware is unable to locate it:
ipw2200: Detected Intel PRO/Wireless 2200BG Network Connection
ipw2200: ipw2200-bss.fw request_firmware failed: Reason -2
errno-base.h defines this as:
#define ENOENT 2 /* No such file or directory */
(The function returning ENOENT puts a minus in front of it.)
I tried creating a symlink in /lib/firmware where my kernel's name pointed to the 2.6.24-24-generic directory, however this resulted in the same error. This firmware is non-GPL, provided by Intel and packed by Ubuntu. I don't believe it has any actual tie to a particular kernel version. cmp shows that the versions in the various directories are identical.
So how does the kernel know where to look for firmware?
Update
I found this solution to the exact problem I'm having, however it no longer works as Ubuntu has eliminated /etc/hotplug.d and no longer stores its firmware in /usr/lib/hotplug/firmware.
Update2
Some more research turned up some more answers. Up until version 92 of udev, the program firmware_helper was the way firmware got loaded. Starting with udev 93 this program was replaced with a script named firmware.sh providing identical functionality as far as I can tell. Both of these hardcode the firmware path to /lib/firmware. Ubuntu still seems to be using the /lib/udev/firmware_helper binary.
The name of the firmware file is passed to firmware_helper in the environment variable $FIRMWARE which is concatenated to the path /lib/firmware and used to load the firmware.
The actual request to load the firmware is made by the driver (ipw2200 in my case) via the system call:
request_firmware(..., "ipw2200-bss.fw", ...);
Now somewhere in between the driver calling request_firmware and firmware_helper looking at the $FIRMWARE environment variable, the kernel package name is getting prepended to the firmware name.
So who's doing it?
From the kernel's perspective, see /usr/src/linux/Documentation/firmware_class/README:
kernel(driver): calls request_firmware(&fw_entry, $FIRMWARE, device)
userspace:
- /sys/class/firmware/xxx/{loading,data} appear.
- hotplug gets called with a firmware identifier in $FIRMWARE
and the usual hotplug environment.
- hotplug: echo 1 > /sys/class/firmware/xxx/loading
kernel: Discard any previous partial load.
userspace:
- hotplug: cat appropriate_firmware_image > \
/sys/class/firmware/xxx/data
kernel: grows a buffer in PAGE_SIZE increments to hold the image as it
comes in.
userspace:
- hotplug: echo 0 > /sys/class/firmware/xxx/loading
kernel: request_firmware() returns and the driver has the firmware
image in fw_entry->{data,size}. If something went wrong
request_firmware() returns non-zero and fw_entry is set to
NULL.
kernel(driver): Driver code calls release_firmware(fw_entry) releasing
the firmware image and any related resource.
The kernel doesn't actually load any firmware at all. It simply informs userspace, "I want a firmware by the name of xxx", and waits for userspace to pipe the firmware image back to the kernel.
Now, on Ubuntu 8.04,
$ grep firmware /etc/udev/rules.d/80-program.rules
# Load firmware on demand
SUBSYSTEM=="firmware", ACTION=="add", RUN+="firmware_helper"
so as you've discovered, udev is configured to run firmware_helper when the kernel asks for firmware.
$ apt-get source udev
Reading package lists... Done
Building dependency tree
Reading state information... Done
Need to get 312kB of source archives.
Get:1 http://us.archive.ubuntu.com hardy-security/main udev 117-8ubuntu0.2 (dsc) [716B]
Get:2 http://us.archive.ubuntu.com hardy-security/main udev 117-8ubuntu0.2 (tar) [245kB]
Get:3 http://us.archive.ubuntu.com hardy-security/main udev 117-8ubuntu0.2 (diff) [65.7kB]
Fetched 312kB in 1s (223kB/s)
gpg: Signature made Tue 14 Apr 2009 05:31:34 PM EDT using DSA key ID 17063E6D
gpg: Can't check signature: public key not found
dpkg-source: extracting udev in udev-117
dpkg-source: unpacking udev_117.orig.tar.gz
dpkg-source: applying ./udev_117-8ubuntu0.2.diff.gz
$ cd udev-117/
$ cat debian/patches/80-extras-firmware.patch
If you read the source, you'll find that Ubuntu wrote a firmware_helper which is hard-coded to first look for /lib/modules/$(uname -r)/$FIRMWARE, then /lib/modules/$FIRMWARE, and no other locations. Translating it to sh, it does approximately this:
echo -n 1 > /sys/$DEVPATH/loading
cat /lib/firmware/$(uname -r)/$FIRMWARE > /sys/$DEVPATH/data \
|| cat /lib/firmware/$FIRMWARE > /sys/$DEVPATH/data
if [ $? = 0 ]; then
echo -n 1 > /sys/$DEVPATH/loading
echo -n -1 > /sys/$DEVPATH/loading
fi
which is exactly the format the kernel expects.
To make a long story short: Ubuntu's udev package has customizations that always look in /lib/firmware/$(uname -r) first. This policy is being handled in userspace.
Wow this is very useful information and it led me to the solution for my problem when making a custom USB kernel module for a device requiring firmware.
Basically, every Ubuntu brings a new rehash of hal,sysfs,devfs,udev,and so on...and things just change. In fact I read they stopped using hal.
So let's reverse engineer this yet again so it's pertinent to the latest [Ubuntu] systems.
On Ubuntu Lucid (the latest at time of writing), /lib/udev/rules.d/50-firmware.rules is used. This file calls the binary /lib/udev/firmware, where magic happens.
Listing: /lib/udev/rules.d/50-firmware.rules
# firmware-class requests, copies files into the kernel
SUBSYSTEM=="firmware", ACTION=="add", RUN+="firmware --firmware=$env{FIRMWARE} --devpath=$env{DEVPATH}"
The magic should be something along these lines (source: Linux Device Drivers, 3rd Ed., Ch. 14: The Linux Device Model):
echo 1 to loading
copy firmware to data
on failure, echo -1 to loading and halt firmware loading process
echo 0 to loading (signal the kernel)
then, a specific kernel module receives the data and pushes it to the device
If you look at Lucid's source page for udev, in udev-151/extras/firmware/firmware.c, the source for that firmware /lib/udev/firmware binary, that's exactly what goes on.
Excerpt: Lucid source, udev-151/extras/firmware/firmware.c
util_strscpyl(datapath, sizeof(datapath), udev_get_sys_path(udev), devpath, "/data", NULL);
if (!copy_firmware(udev, fwpath, datapath, statbuf.st_size)) {
err(udev, "error sending firmware '%s' to device\n", firmware);
set_loading(udev, loadpath, "-1");
rc = 4;
goto exit;
};
set_loading(udev, loadpath, "0");
Additionally, many devices use an Intel HEX format (textish files containing checksum and other stuff) (wiki it i have no reputation and no ability to link). The kernel program ihex2fw (called from Makefile in kernel_source/lib/firmware on .HEX files) converts these HEX files to an arbitrary-designed binary format that the Linux kernel then picks up with request_ihex_firmware, because they thought reading text files in the kernel was silly (it would slow things down).
On current Linux systems, this is handled via udev and the firmware.agent.
Linux 3.5.7 Gentoo, I have the same issue.
SOLVED:
emerge ipw2200-firmware
Then go to /usr/src/linux
make menucofig
on device driver, remove all wirless drivers don't needed, set Intell 2200 as module and recompile.
make
make modules_install
cp arch/x86/boot/bzImage /boot/kernel-yourdefault