Perf: kernel module symbols not showing up in profiling - linux

On loading and running a kernel module and then profiling through perf.
$perf record -a -g --call-graph dwarf sleep 30'
$perf report
my kernel module's symbols are not present in the perf's report.
Although the symbols are present in /proc/kallsyms.
Also the module is not present in perf buildid-list
As this answer says to make the module a kernel module, I tried but didn't help.
What are the possible reasons that could lead to this?

The message Failed to open [thrUserCtrl], continuing without symbols sounds like perf was unable to find your module. Try installing it into
/lib/modules/`uname -r`/extra
directory as said in https://wiki.centos.org/HowTos/BuildingKernelModules:
6. In this example, the file cifs.ko has just been created.
As root, copy the .ko file to the /lib/modules/<kernel-version>/extra/
directory.
[root#host linux-2.6.18.i686]# cp fs/cifs/cifs.ko /lib/modules/`uname -r`/extra
(don't forget depmod -a command after changing files in /lib/modules)
This message is generated in map__load: http://elixir.free-electrons.com/linux/v4.11/source/tools/perf/util/map.c#L284
int map__load(struct map *map)
{
const char *name = map->dso->long_name;
int nr;
...
nr = dso__load(map->dso, map);
if (nr < 0) {
if (map->dso->has_build_id) {
...
} else
pr_warning("Failed to open %s", name);
pr_warning(", continuing without symbols\n");
return -1;
when dso__load function returns error.

Related

bpftrace: uprobe target file does not exist or is not executable

I want to use bpftrace to trace functions inside libasan library, which is inside /usr/lib/x86_64-linux-gnu/.
However
sudo bpftrace -e 'uretprobe:/usr/lib/x86_64-linux-gnu/libasan.so.4: __interceptor_malloc { printf("pid: %d, malloc %p\n", pid, retval); }'
gives error: uprobe target file '/usr/lib/x86_64-linux-gnu/libasan.so.4' does not exist or is not executable
I have tried: export LD_LIBRARY_PATH="/lib:/usr/lib:/usr/local/lib" but it does not help.
How can make the library executable for bpftrace? I need it to trace allocations done in a Firefox process. Thanks!
EDIT: I just found out that the permission on libasan is -rw-r--r--, which means it is indeed not executable. How should I make it executable?
I fixed it by doing chmod +x libasan.so.4.0.0

no core dump in /var/crash

I am trying to understand a bit how the core dump work.
I use the test.c file to generate a core dump :
#include <stdio.h>
void foo()
{
int *ptr = 0;
*ptr = 7;
}
int main()
{
foo();
return 0;
}
I compile with
gcc test.c -o test
Which gives me the following message when I run ./test
Segmentation fault (core dumped)
My file
/proc/sys/kernel/core_pattern
contains :
|/usr/share/apport/apport %p %s %c %d %P
I checked that I have the permissions to write to the directory
/var/crash/
but after the core dump there is nothing in this folder (/var/crash/).
I am using Linux release 17.04.
Do you know what can go wrong here?
edit
I forgot to mention that I set the limits with :
ulimit -c unlimited
so the output of
ulimit -c
reads :
unlimited
I even tried to do what they say here in section How to enable apport, so I added a hash sign in front of
'problem_types': ['Bug', 'Package']
But with all of this the core dump cannot be found in /var/cash
This link contains a checklist for why coredump is not generated. Adding the list below in case link becomes inaccessible in future.
The core would have been larger than the current limit.
You don't have the necessary permissions to dump core (directory and file). Notice that core dumps are placed in the dumping process' current directory which could be different from the parent process.
Verify that the file system is writeable and have sufficient free space.
If a sub directory named core exist in the working directory no core will be dumped.
If a file named core already exist but has multiple hard links the kernel will not dump core.
Verify the permissions on the executable, if the executable has the suid or sgid bit enabled core dumps will by default be disabled. The same will be the case if you have execute permissions but no read permissions on the file.
Verify that the process has not changed working directory, core size limit, or dumpable flag.
Some kernel versions cannot dump processes with shared address space (AKA threads). Newer kernel versions can dump such processes but will append the pid to the file name.
The executable could be in a non-standard format not supporting core dumps. Each executable format must implement a core dump routine.
The segmentation fault could actually be a kernel Oops, check the system logs for any Oops messages.
The application called exit() instead of using the core dump handler.
I was also struggling to get coredumps and I had the same problem with ulimit. The session specific setting suggested by Niranjan also didn't work for me.
Finally I found the solution at https://serverfault.com/questions/216656/how-to-set-systemwide-ulimit-on-ubuntu
in /etc/security/limits.conf add:
root - core unlimited
* - core unlimited
And log out / log in.
Then
ulimit -c
on the terminal should return "unlimited" and core dumps are generated.
What filesize limit have you set for coredumps in your machine?
You can check it using
$ ulimit -c
If it is set to 0, then no coredumps will be generated - This is the default setting in most distros.
You can enable coredumps by setting it to 'unlimited' or using a specific filesize limit.
$ ulimit -c unlimited

Cannot locate core file with abrt-hook-cpp installed

I've been led to understand that if abrt-ccpp.service is installed on a Linux PC, it supersedes/overwrites (I've read both, not sure which is true) the file /proc/sys/kernel/core_pattern, which otherwise specifies the location and filename pattern of core files.
Question:
When I execute systemctl, why does abrt-ccpp.service report exited under the SUB column? I don't understand the combination of active and exited: is the service "alive"/active/running or not?
> systemctl
UNIT LOAD ACTIVE SUB
abrt-ccpp.service loaded active exited ...
Question:
Where are core files generated? I wrote this program to generate a SIGSEGV:
#include <iostream>
int main(int argc, char* argv[], char* envz[])
{
int* pInt = NULL;
std::cout << *pInt << std::endl;
return 0;
}
Compilation and execution as follows:
> g++ main.cpp
> ./a.out
Segmentation fault (core dumped)
But I cannot locate where the core file is generated.
What I have tried:
Looked in the same directory as my main.cpp. Core file is not there.
Looked in /var/tmp/abrt/ because of the following comment in /etc/abrt/abrt.conf. Core file is not there.
...
# Specify where you want to store coredumps and all files which are needed for
# reporting. (default:/var/tmp/abrt)
#
# Changing dump location could cause problems with SELinux. See man_abrt_selinux(8).
#
#DumpLocation = /var/tmp/abrt
...
Looked in /var/spool/abrt/ because of a comment at this link. Core file is not there.
Edited /etc/abrt/abrt.conf and uncommented and set DumpLocation = ~/foo which is an existing directory. Followed this by restarting abrt-hook-ccpp (sudo service abrt-ccpp restart) and rerunning a.out. Core file was not generated in ~/foo/
Verified that ulimit -c reports unlimited.
I am out of ideas of what else to try and where else to look.
In case helpful, this is the content of my /proc/sys/kernel/core_pattern:
> cat /proc/sys/kernel/core_pattern
|/usr/libexec/abrt-hook-ccpp %s %c %p %u %g %t e
Can someone help explain how the abrt-hook-ccpp service works and where it generates core files? Thank you.
I'd like to credit https://unix.stackexchange.com/users/119298/meuh who answered this at https://unix.stackexchange.com/questions/343240/cannot-locate-core-file-with-abrt-hook-cpp-installed.
The answer was to add this line in file /etc/abrt/abrt-action-save-package-data.conf
ProcessUnpackaged = yes
The comment from #daniel-kamil-kozar was also a viable workaround.

How to generate core dump file in Linux?

I am trying to generate the core dump file using the below program in Linux.
#include <stdio.h>
#include<iostream>
using namespace std;
int main()
{
char *temp ="ABCDE";
int i =0;
temp[3] ='F';
for (i =0; i <5; i++)
printf("% Value is %c\n", temp[i]);
cout<<"Done"<<endl;
return 0;
}
I saved the above source code as sample.cpp and build the file using the below command.
g++ sample.cpp -g -o test
Run the output file "test" which produced the error "Segmentation fault". But it didn't generate the core dump file.
./test
I refereed this . Thanks for your help.
The generation of core dump files it is not always enabled. Try with the ulimit command.
Some systems are configured not to write core files by default, since the files can be large and rapidly fill up the available disk space on a system. In the GNU Bash shell the command ulimit -c controls the maximum size of core files. If the size limit is zero, no core files are produced. The current size limit can be shown by typing the following command:
$ ulimit -c
0
If the result is zero, as shown above, then it can be increased with the following command to allow core files of any size to be written:(17)
$ ulimit -c unlimited

How to remove warning: link.res contains output sections; did you forget -T?

I'm using fpc compiler and I want to remove this warning. I've read fpc's options but I can't find how to do that. Is this possible?
it appear when I run command:
fpc foo.pas
out:
Target OS: Linux for i386 Compiling foo.pas Linking p2 /usr/bin/ld:
warning: link.res contains output sections; did you forget -T? 79
lines compiled, 0.1 sec
It's a bug in certain LD versions. Just ignore it for now, or see if your distro has an update for your LD. (package binutils)
http://www.freepascal.org/faq.var#unix-ld219
It‘s not a bug because ld behaves like its specification. The man page of ld 2.28 reads:
If the linker cannot recognize the format of an object file, it will assume that it is a linker script. A script specified in this way augments the main linker script used for the link (either the default linker script or the one specified by using -T). This feature permits the linker to link against a file which appears to be an object or an archive, but actually merely defines some symbol values, or uses "INPUT" or "GROUP" to load other objects. Specifying a script in this way merely augments the main linker script, with the extra commands placed after the main script; use the -T option to replace the default linker script entirely, but note the effect of the "INSERT" command.
TL;DR ☺. In a nutshell: In most cases the users are not aware of the linker script they are using because a “main script” (= default script) is provided by the tool chain. The main script heavily refers to intrinsics of the compiler-generated sections and you have to learn the ropes to change it. Most users do not.
The common approach to provide your own script is via the -T option. That way the main linker script is ignored and your script takes over control over the linkage. But you have to write everything from scratch.
If you just want to add a minor feature, you can write your specs into a file and append the file name to the command line of ld (or gcc / g++) without the -T option. That way the main linker script still does the chief work but your file augments it. If you use this approach, you get the message of the header of this thread to inform you that you might have provided a broken object unintentionally.
The source of this confusion is that there is no way to specify the rôle of the additional file. This could easily be resolved by adding another option to ld just like the -dT option for “default scriptfile”: Introduce a -sT option for “supplemental scriptfile”.
This is fixed in version 2.35.1 (or later) of binutils.
If you have a problematic version of binutils, I've created a quick program to binary patch /usr/bin/ld to silence this extremely annoying warning message.
This program can be saved as main.go and be executed with sudo go run main.go to patch ld. Remember to take a backup of ld first and modify the path in the main function, if your binary is placed elsewhere.
main.go:
package main
import (
"bytes"
"fmt"
"io/ioutil"
"os"
)
// patchAway takes a filename and a string
// If the string is found in the file, the first byte is
// set to 0, to make the string zero length in C.
func patchAway(filename, cstring string) error {
data, err := ioutil.ReadFile(filename)
if err != nil {
return err
}
// Find the position of the warning
pos := bytes.Index(data, []byte(cstring))
// If it does not exist, the file has most likely already been patched
if pos == -1 {
return fmt.Errorf("%s has already been patched", filename)
}
// Silence the message with a 0 byte
data[pos] = 0
// Retrieve the permissions of the original file
fi, err := os.Stat(filename)
if err != nil {
return err
}
perm := fi.Mode().Perm()
// Write the patched data to the new file, but with the same permissions as the original file
return ioutil.WriteFile(filename, data, perm)
}
func main() {
filename := "/usr/bin/ld"
warningMessage := "%P: warning: %s contains output sections"
fmt.Printf("Patching %s... ", filename)
if err := patchAway(filename, warningMessage); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
fmt.Println("ok")
}

Resources