Why isn't my kernel extension writing to kernel.log - macos

I have a simple kernel extension:
kern_return_t HelloWorld_start (kmod_info_t *ki, void * d) {
printf("Hello World\n");
return KERN_SUCCESS;
}
kern_return_t HelloWorld_stop (kmod_info_t * kid, void * d) {
printf("Goodbye World\n");
return KERN_SUCCESS;
}
Which I'm compiling and loading via:
sudo kextload HelloWorld.kext
And it appears in the kextstat listing:
...
129 0 0xffffff7f80fac000 0x4000 0x4000 com.apple.driver.AppleProfileThreadInfoAction (85.2) <123 6 4 3 1>
130 0 0xffffff7f80fb0000 0x4000 0x4000 com.apple.driver.AppleProfileTimestampAction (85.2) <123 5 4 3 1>
132 0 0xffffff7f807c6000 0x2000 0x2000 sk-r-d.HelloWorld (1) <4>
However, I have nothing in kernel.log (or system.log) - I should be seeing my printf() statements. Any idea why?

For some reason the console app doesn't seem to display printf messages from kexts, but the log console program does.
I've had success with the following magic words...
log stream --predicate 'eventMessage contains "YourMatchingPatternHere"'
This will produce a filtered stream showing only messages that match your predefined pattern.

sudo nvram boot-args="kext-dev-mode=1 debug=0x22"

Related

How can I get the BSOD bugcheck code text description by code/windows API

I can get the bugcheck code and the parameters for one BSOD.
And then I can get the text descriptions from Bug Check Code Reference.
But how can I use some windows API or c++ code to get such text description from the bugcheck code and parameters.
For example, for the bugcheck code 0x9F, how can I get the text as
DRIVER_POWER_STATE_FAILURE (9f)
A driver has failed to complete a power IRP within a specific time.
with some windows API or reading from some DLL.
Or to say, how to implement similar function as WinDbg :
1: kd> !analyze -show 0x9F 0x3
DRIVER_POWER_STATE_FAILURE (9f)
A driver has failed to complete a power IRP within a specific time.
Arguments:
Arg1: 0000000000000003, A device object has been blocking an Irp for too long a time
Arg2: 0000000000000000, Physical Device Object of the stack
Arg3: 0000000000000000, nt!TRIAGE_9F_POWER on Win7 and higher, otherwise the Functional Device Object of the stack
Arg4: 0000000000000000, The blocked IRP
I saw there's API like KeGetBugMessageText(), but it's preserved by Windows itself.
Could someone help on this and give some clue or suggestion on that?
Update:
The main part of code used to execute command with 'blabb' suggestion:
#pragma comment ( lib ,"dbgeng.lib")
#include <iostream>
#include <dbgeng.h>
#include "StdioOutputCallbacks.h"
//#include <wdbgexts.h>
//WINDBG_EXTENSION_APIS64 ExtensionApis;
StdioOutputCallbacks g_OutputCb;
int main()
{
IDebugClient* DebugClient = NULL;
HRESULT Hr = S_OK;
if ((Hr = DebugCreate(__uuidof(IDebugClient),
(void**)&DebugClient)) != S_OK) {
return Hr;
}
PDEBUG_CONTROL DebugControl;
if ((Hr = DebugClient->QueryInterface(__uuidof(IDebugControl),
(void**)&DebugControl)) == S_OK) {
DebugClient->SetOutputCallbacks(&g_OutputCb);
Hr = DebugClient->OpenDumpFile("C:\\Dev\\Deem\\bug\\dcp938\\MEMORY.DMP");
if (Hr != S_OK) {
return Hr;
}
DebugControl->Execute(DEBUG_OUTCTL_THIS_CLIENT, "!analyze -show 9f 3", DEBUG_EXECUTE_DEFAULT);
DebugControl->Release();
}
// done
DebugClient->Release();
}
and in outputcallback, kept as the msdn sample:
STDMETHODIMP
StdioOutputCallbacks::Output(
THIS_
_In_ ULONG Mask,
_In_ PCSTR Text
)
{
UNREFERENCED_PARAMETER(Mask);
fputs(Text, stdout);
return S_OK;
}
But the result of the execute "!analyze -show 9f 3"(the content of Text in fputs()) is "No export analyze found".
I also try the command ".opendump C:\...MEMORY.DMP;!analyze -show 9f 3", the opendump command executed correctly, the dmp is loaded and got the text output including "For analysis of this file, run !analyze -v", but both "!analyze -v" and "!analyze -show ..." got "No export analyze found".
The command without '!' will lead to command resolve error.
I am not sure what you are looking for.
All these are #defined in bugcodes.h in windows sdk/ddk
C:\Program Files (x86)\Windows Kits\10\Include>pss DRIVER_POWER_STATE_FAILURE
.\10.0.17763.0\shared\bugcodes.h
1505:// MessageId: DRIVER_POWER_STATE_FAILURE
1509:// DRIVER_POWER_STATE_FAILURE
1511:#define DRIVER_POWER_STATE_FAILURE ((ULONG)0x0000009FL)
Or grepping the other way round
C:\Program Files (x86)\Windows Kits\10\Include>grep -ir #define.*0x0000009fl --include *.h *
10.0.17763.0/shared/bugcodes.h:#define DRIVER_POWER_STATE_FAILURE ((ULONG)0x0000009FL)
Or use DbgEng to write either a WinDbg extension or a standalone executable.
Open the dump->WaitForEvent->Executecommands !bugdump .bug****
Or you can also explore IDebugDataSpaces::****tag**** methods like read, start, next, end.
Edit
Scott Noone is probably indicating the ext.dll the inbuilt windbg extension
As i Already Stated you may need to write a windbg Analyze Extension either as an extension or as a standalone
most of these are either undocumented or poorly worded documentation
here is the dump of bugcheck codes compiled inside ext.dll which is what scott noone is probably indicating in his answer.
0:000> dps ext!g_BugCheckApiRefs l10
00007ff9`4a45ccc0 00000000`00000001
00007ff9`4a45ccc8 00007ff9`49efead0 ext!BugCheckAPC_INDEX_MISMATCH
00007ff9`4a45ccd0 00000000`00000002
00007ff9`4a45ccd8 00007ff9`49efeb60 ext!BugCheckDEVICE_QUEUE_NOT_BUSY
00007ff9`4a45cce0 00000000`00000003
00007ff9`4a45cce8 00007ff9`49efebc0 ext!BugCheckINVALID_AFFINITY_SET
00007ff9`4a45ccf0 00000000`00000004
00007ff9`4a45ccf8 00007ff9`49efec20 ext!BugCheckINVALID_DATA_ACCESS_TRAP
00007ff9`4a45cd00 00000000`00000005
00007ff9`4a45cd08 00007ff9`49efec80 ext!BugCheckINVALID_PROCESS_ATTACH_ATTEMPT
00007ff9`4a45cd10 00000000`00000006
00007ff9`4a45cd18 00007ff9`49efece0 ext!BugCheckINVALID_PROCESS_DETACH_ATTEMPT
00007ff9`4a45cd20 00000000`00000007
00007ff9`4a45cd28 00007ff9`49efed40 ext!BugCheckINVALID_SOFTWARE_INTERRUPT
00007ff9`4a45cd30 00000000`00000008
00007ff9`4a45cd38 00007ff9`49efeda0 ext!BugCheckIRQL_NOT_DISPATCH_LEVEL
0:000>
or your power failure
0:000> .shell -ci "dps ext!g_BugCheckApiRefs l150" grep -A 1 -i 09f
00007ff9`4a45d600 00000000`0000009f
00007ff9`4a45d608 00007ff9`49f04450 ext!BugCheckDRIVER_POWER_STATE_FAILURE
.shell: Process exited
0:000>
here is a complete call stackLeadign to yourQuery about !analyze -show 9f 3
Child-SP RetAddr Call Site
000000d3`6d67b768 00007ff9`49fa302a ext!GetBugCheckDescription
000000d3`6d67b770 00007ff9`49f822c2 ext!DebugFailureAnalysis::ParseInputArgs+0xc66
000000d3`6d67bb00 00007ff9`49f549c5 ext!AnalyzeBugCheck+0x10a
000000d3`6d67bbd0 00007ff9`4ae0187d ext!analyze+0x4e5
000000d3`6d67bd90 00007ff9`4ae01a31 dbgeng!ExtensionInfo::CallA+0x27d
000000d3`6d67be50 00007ff9`4ae01d0e dbgeng!ExtensionInfo::Call+0x121
000000d3`6d67c050 00007ff9`4adff9d8 dbgeng!ExtensionInfo::CallAny+0x17a
000000d3`6d67c570 00007ff9`4ae43662 dbgeng!ParseBangCmd+0xe0c
000000d3`6d67cd30 00007ff9`4ae44635 dbgeng!ProcessCommands+0xcd6
000000d3`6d67ce20 00007ff9`4ad6baf7 dbgeng!ProcessCommandsAndCatch+0x79
000000d3`6d67ce90 00007ff9`4ad6be04 dbgeng!Execute+0x2bb
000000d3`6d67d380 00007ff6`4c7b62dc dbgeng!DebugClient::ExecuteWide+0x94
000000d3`6d67d3e0 00007ff6`4c7b879a kd!MainLoop+0x514
000000d3`6d67f460 00007ff6`4c7bb55d kd!wmain+0x3e6
000000d3`6d67f700 00007ff9`857c7c24 kd!__wmainCRTStartup+0x14d
000000d3`6d67f740 00007ff9`85d8d721 KERNEL32!BaseThreadInitThunk+0x14
000000d3`6d67f770 00000000`00000000 ntdll!RtlUserThreadStart+0x21
0:000>
The Function is a simple compare return routine like
while array[i] != 0x9f skip
return String array[i]+0x8
and the detailed description is done by
void PrintBugDescription(_BUGCHECK_ANALYSIS *param_1,DebugFailureAnalysis *param_2)
EDIT
Since My last comment I was wondering
how I would go about this scenario without writing code
without having a kernel memory dump to operate on
possibly scalable to unknown remote machines
I Came up with a small python wrapper using sysinternals livekd.exe
script
:\>cat liv.py
import subprocess
import regex
foo = subprocess.run(
[r"f:\sysint\livekd", "-b" ,"-c \"!analyze -show 9f 03;q\""],
stdout=subprocess.PIPE,
universal_newlines=True
)
resta = regex.search("Reading" , foo.stdout).start()
reend = regex.search("quit:" , foo.stdout).end()
print(foo.stdout[resta:reend])
result of script execution
:\>python liv.py
Reading initial command '!analyze -show 9f 03;q'
*** ERROR: Module load completed but symbols could not be loaded for LiveKdD.SYS
DRIVER_POWER_STATE_FAILURE (9f)
A driver has failed to complete a power IRP within a specific time.
Arguments:
Arg1: 0000000000000003, A device object has been blocking an Irp for too long a time
Arg2: 0000000000000000, Physical Device Object of the stack
Arg3: 0000000000000000, nt!TRIAGE_9F_POWER on Win7 and higher, otherwise the Functional Device Object of the stack
Arg4: 0000000000000000, The blocked IRP
*******************************************************************************
* *
* Bugcheck Analysis *
* *
*******************************************************************************
Use !analyze -v to get detailed debugging information.
BugCheck 0, {0, 0, 0, 0}
Probably caused by : LiveKdD.SYS ( LiveKdD+2f4f )
Followup: MachineOwner
---------
quit:
Adding another answer as the prior answer is too cluttered and commented.
contents of directory pre compilation and linking
F:\bugdesc>ls -lg
-rw-r--r-- 1 197121 156689581 Aug 17 23:49 MEMORY.DMP
-rw-r--r-- 1 197121 600 Aug 26 01:22 bugdesc.cpp
-rw-r--r-- 1 197121 109 Aug 19 00:04 complink.bat
-rw-r--r-- 1 197121 1019 Aug 26 01:21 stdioimpl.h
contents of bat file
F:\bugdesc>cat complink.bat
cl /nologo /W4 /Od /Zi /EHsc /I"C:\Program Files (x86)\Windows Kits\10\Debuggers\inc" %1.cpp /link /RELEASE
file containing implementation of StdioOutputCallbacks
F:\bugdesc>cat stdioimpl.h
#include <windows.h>
#include <stdio.h>
#include <dbgeng.h>
#pragma comment(lib, "dbgeng.lib")
class StdioOutputCallbacks : public IDebugOutputCallbacks {
public:
STDMETHOD(QueryInterface)(THIS_ _In_ REFIID ifid, _Out_ PVOID *iface);
STDMETHOD_(ULONG, AddRef)(THIS);
STDMETHOD_(ULONG, Release)(THIS);
STDMETHOD(Output)(THIS_ IN ULONG Mask, IN PCSTR Text);
};
STDMETHODIMP
StdioOutputCallbacks::QueryInterface(THIS_ _In_ REFIID ifid, _Out_ PVOID *iface){
*iface = NULL;
if (IsEqualIID(ifid, __uuidof(IDebugOutputCallbacks))){
*iface = (IDebugOutputCallbacks *)this;
AddRef();
return S_OK;
} else {
return E_NOINTERFACE;
}
}
STDMETHODIMP_(ULONG)
StdioOutputCallbacks::AddRef(THIS) { return 1; }
STDMETHODIMP_(ULONG)
StdioOutputCallbacks::Release(THIS) { return 0; }
STDMETHODIMP StdioOutputCallbacks::Output(THIS_ IN ULONG, IN PCSTR Text){
fputs(Text, stdout);
return S_OK;
}
contents of main source file
F:\bugdesc>cat bugdesc.cpp
#include "stdioimpl.h"
//implement proper error handling and release of Interfaces
void __cdecl main(void)
{
IDebugClient *g_Client;
IDebugControl *g_Control;
StdioOutputCallbacks g_OutputCb;
DebugCreate(__uuidof(IDebugClient), (void **)&g_Client);
g_Client->QueryInterface(__uuidof(IDebugControl), (void **)&g_Control);
g_Client->SetOutputCallbacks(&g_OutputCb);
g_Client->SetOutputCallbacks(&g_OutputCb);
g_Client->OpenDumpFile("F:\\bugdesc\\memory.dmp");
g_Control->WaitForEvent(0, INFINITE);
g_Control->Execute(0, "!analyze -show 9f 3", 0);
}
compiled and linked with vs-community 2017 as x64
F:\bugdesc>complink.bat bugdesc
F:\bugdesc>cl /nologo /W4 /Od /Zi /EHsc /I"C:\Program Files (x86)\Windows Kits\10\Debuggers\inc" bugdesc.cpp /link /RELEASE
bugdesc.cpp
contents of directory post compilation and linking
F:\bugdesc>ls -lg
total 159485
-rw-r--r-- 1 197121 156689581 Aug 17 23:49 MEMORY.DMP
-rw-r--r-- 1 197121 600 Aug 26 01:22 bugdesc.cpp
-rwxr-xr-x 1 197121 406016 Aug 26 01:25 bugdesc.exe
-rw-r--r-- 1 197121 30072 Aug 26 01:25 bugdesc.obj
-rw-r--r-- 1 197121 5992448 Aug 26 01:25 bugdesc.pdb
-rw-r--r-- 1 197121 109 Aug 19 00:04 complink.bat
-rw-r--r-- 1 197121 1019 Aug 26 01:21 stdioimpl.h
-rw-r--r-- 1 197121 176128 Aug 26 01:25 vc140.pdb
executing without proper dlls and failure
F:\bugdesc>bugdesc.exe
No .natvis files found at C:\WINDOWS\SYSTEM32\Visualizers.
xxxxxxxxxxxxxxxxxxxxxxxxxxx snip
Microsoft (R) Windows Debugger Version 10.0.18362.1 AMD64
xxxxxxxxxxxxxxxxxxxxxxxxxxx snip
Loading Dump File [F:\bugdesc\memory.dmp]
xxxxxxxxxxxxxxxxxxxxxxxxxxx snip
*** Type referenced: nt!_MMPTE_TRANSITION ***
xxxxxxxxxxxxxxxxxxxxxxxxxxx snip
For analysis of this file, run !analyze -v
No export analyze found<<<<<<<<<<<<<<<<<<
copying relevent dlls from windbg installation folder
F:\bugdesc>copy ..\windbg_dlls\*.* .
..\windbg_dlls\dbgeng.dll
..\windbg_dlls\dbghelp.dll
..\windbg_dlls\ext.dll
..\windbg_dlls\symsrv.dll
4 file(s) copied.
execution and success
F:\bugdesc>bugdesc.exe
Microsoft (R) Windows Debugger Version 10.0.17763.132 AMD64
xxxxxxxxxxxxxxxxxxxxxxxxxxx snip
Loading Dump File [F:\bugdesc\memory.dmp]
xxxxxxxxxxxxxxxxxxxxxxxxxxx snip
*******************************************************************************
* *
* Bugcheck Analysis *
* *
*******************************************************************************
Use !analyze -v to get detailed debugging information.
BugCheck E2, {0, 0, 0, 0}
Probably caused by : Unknown_Image
*** Followup info cannot be found !!! Please contact "BADEV"
---------
DRIVER_POWER_STATE_FAILURE (9f)<<<<<<<<<<<<<<<<<<<<<<<
A driver has failed to complete a power IRP within a specific time.
Arguments:
Arg1: 0000000000000003, A device object has been blocking an Irp for too long a time
Arg2: 0000000000000000, Physical Device Object of the stack
Arg3: 0000000000000000, nt!TRIAGE_9F_POWER on Win7 and higher, otherwise the Functional Device Object of the stack
Arg4: 0000000000000000, The blocked IRP
xxxxxxxxxxxxxxxxxxxxxxxxxxx snip

Yocto Patch Linux Kernel In-Tree-Module with extern symbol exported from Out-Of-Tree Module

I am using Yocto to build an SD Card image for my Embedded Linux Project. The Yocto branch is Warrior and the Linux kernel version is 4.19.78-linux4sam-6.2.
I am currently working on a way to read memory from an external QSPI device in the initramfs and stick the contents into a file in procfs. That part works and I echo data into the proc file and read it out successfully later in user space Linux after the board has booted.
Now I need to use the Linux Kernel module EXPORT_SYMBOL() functionality to allow an in-tree kernel module to know about my out-of-tree custom kernel module exported symbol.
In my custom module, I do this:
static unsigned char lan9730_mac_address_buffer[6];
EXPORT_SYMBOL(lan9730_mac_address_buffer);
And I patched the official kernel build in a bitbake bbappend file with this:
diff -Naur kernel-source/drivers/net/usb/smsc95xx.c kernel-source.new/drivers/net/usb/smsc95xx.c
--- kernel-source/drivers/net/usb/smsc95xx.c 2020-08-04 22:34:02.767157368 +0000
+++ kernel-source.new/drivers/net/usb/smsc95xx.c 2020-08-04 23:34:27.528435689 +0000
## -917,6 +917,27 ##
{
const u8 *mac_addr;
+ printk("=== smsc95xx_init_mac_address ===\n");
+ printk("%x:%x:%x:%x:%x:%x\n",
+ lan9730_mac_address_buffer[0],
+ lan9730_mac_address_buffer[1],
+ lan9730_mac_address_buffer[2],
+ lan9730_mac_address_buffer[3],
+ lan9730_mac_address_buffer[4],
+ lan9730_mac_address_buffer[5]);
+ printk("=== mac_addr is set ===\n");
+ if (lan9730_mac_address_buffer[0] != 0xff &&
+ lan9730_mac_address_buffer[1] != 0xff &&
+ lan9730_mac_address_buffer[2] != 0xff &&
+ lan9730_mac_address_buffer[3] != 0xff &&
+ lan9730_mac_address_buffer[4] != 0xff &&
+ lan9730_mac_address_buffer[5] != 0xff) {
+ printk("=== SUCCESS ===\n");
+ memcpy(dev->net->dev_addr, lan9730_mac_address_buffer, ETH_ALEN);
+ return;
+ }
+ printk("=== FAILURE ===\n");
+
/* maybe the boot loader passed the MAC address in devicetree */
mac_addr = of_get_mac_address(dev->udev->dev.of_node);
if (!IS_ERR(mac_addr)) {
diff -Naur kernel-source/drivers/net/usb/smsc95xx.h kernel-source.new/drivers/net/usb/smsc95xx.h
--- kernel-source/drivers/net/usb/smsc95xx.h 2020-08-04 22:32:30.824951447 +0000
+++ kernel-source.new/drivers/net/usb/smsc95xx.h 2020-08-04 23:33:50.486778978 +0000
## -361,4 +361,6 ##
#define INT_ENP_TDFO_ ((u32)BIT(12)) /* TX FIFO Overrun */
#define INT_ENP_RXDF_ ((u32)BIT(11)) /* RX Dropped Frame */
+extern unsigned char lan9730_mac_address_buffer[6];
+
#endif /* _SMSC95XX_H */
However, the Problem is that the Kernel fails to build with this error:
| GEN ./Makefile
| Using /home/me/Desktop/poky/build-microchip/tmp/work-shared/sama5d27-som1-ek-sd/kernel-source as source for kernel
| CALL /home/me/Desktop/poky/build-microchip/tmp/work-shared/sama5d27-som1-ek-sd/kernel-source/scripts/checksyscalls.sh
| Building modules, stage 2.
| MODPOST 279 modules
| ERROR: "lan9730_mac_address_buffer" [drivers/net/usb/smsc95xx.ko] undefined!
How can I refer to the Out-Of-Tree kernel module exported symbol in a patched In-Tree kernel module?
initramfs relevant code:
msg "Inserting lan9730-mac-address.ko..."
insmod /mnt/lib/modules/4.19.78-linux4sam-6.2/extra/lan9730-mac-address.ko
ls -rlt /proc/lan9730-mac-address
head -c 6 /dev/mtdblock0 > /proc/lan9730-mac-address
Out-Of-Tree module:
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/proc_fs.h>
#include <linux/sched.h>
#include <linux/uaccess.h>
#include <linux/slab.h>
const int BUFFER_SIZE = 6;
int write_length, read_length;
unsigned char lan9730_mac_address_buffer[6];
EXPORT_SYMBOL(lan9730_mac_address_buffer);
int read_proc(struct file *filp, char *buf, size_t count, loff_t *offp)
{
// Read bytes (returning the byte count) until all bytes are read.
// Then return count=0 to signal the end of the operation.
if (count > read_length)
count = read_length;
read_length = read_length - count;
copy_to_user(buf, lan9730_mac_address_buffer, count);
if (count == 0)
read_length = write_length;
return count;
}
int write_proc(struct file *filp, const char *buf, size_t count, loff_t *offp)
{
if (count > BUFFER_SIZE)
count = BUFFER_SIZE;
copy_from_user(lan9730_mac_address_buffer, buf, count);
write_length = count;
read_length = count;
return count;
}
struct file_operations proc_fops = {
read: read_proc,
write: write_proc
};
void create_new_proc_entry(void) //use of void for no arguments is compulsory now
{
proc_create("lan9730-mac-address", 0, NULL, &proc_fops);
}
int proc_init (void) {
create_new_proc_entry();
memset(lan9730_mac_address_buffer, 0x00, sizeof(lan9730_mac_address_buffer));
return 0;
}
void proc_cleanup(void) {
remove_proc_entry("lan9730-mac-address", NULL);
}
MODULE_LICENSE("GPL");
module_init(proc_init);
module_exit(proc_cleanup);
There are several ways to achieve what you want (taking into account different aspects, like module can be compiled in or be a module).
Convert Out-Of-Tree module to be In-Tree one (in your custom kernel build). This will require simple export and import as you basically done and nothing special is required, just maybe providing a header with the symbol and depmod -a run after module installation. Note, you have to use modprobe in-tree which reads and satisfies dependencies.
Turn other way around, i.e. export symbol from in-tree module and file it in the out-of-tree. In this case you simply have to check if it has been filed or not (since it's a MAC address the check against all 0's will work, no additional flags needed)
BUT, these ways are simply wrong. The driver and even your patch clearly show that it supports OF (Device Tree) and your board has support of it. So, this is a first part of the solution, you may provide correct MAC to the network card using Device Tree.
In the case you want to change it runtime the procfs approach is very strange to begin with. Network device interface in Linux has all means to update MAC from user space at any time user wants to do it. Just use ip command, like /sbin/ip link set <$ETH> addr <$MACADDR>, where <$ETH> is a network interface, for example, eth0 and <$MACADDR> is a desired address to set.
So, if this question rather about module symbols, you need to find better example for it because it's really depends to use case. You may consider to read How to export symbol from Linux kernel module in this case? as an alternative way to exporting. Another possibility how to do it right is to use software nodes (it's a new concept in recent Linux kernel).

systemtap failed to probe the functions. Registration error

systemtap registration error.
WARNING: probe process("/home/user/a.out").function("func").return inode-offset 00000000468ed0c6 registration error (rc -5)
WARNING: probe process("/home/user/a.out").function("func").call inode-offset 00000000468ed0c6 registration error (rc -5)
WARNING: task_finder mmap inode-uprobes callback for task 28532 failed: -5
I am learning systemtap. I have a process which calls a function in a while loop. When I start systemtap using "stap -v test.stp" to probe the userspace function, I get the registration error. Following is the complete screen shot;
Pass 1: parsed user script and 465 library scripts using 112640virt/48788res/6452shr/42636data kb, in 100usr/20sys/123real ms.
Pass 2: analyzed script: 3 probes, 2 functions, 4 embeds, 3 globals using 114256virt/51968res/7840shr/44252data kb, in 50usr/110sys/162real ms.
Pass 3: using cached /root/.systemtap/cache/66/stap_662fe7689c5fb5d6ef569e8246fa1c8a_3296.c
Pass 4: using cached /root/.systemtap/cache/66/stap_662fe7689c5fb5d6ef569e8246fa1c8a_3296.ko
Pass 5: starting run.
WARNING: probe process("/home/admin/a.out").function("func").return inode-offset 00000000468ed0c6 registration error (rc 0)
WARNING: probe process("/home/admin/a.out").function("func").call inode-offset 00000000468ed0c6 registration error (rc 0)
^CERROR: empty aggregate near operator '#max' at test.stp:6:37
WARNING: Number of errors: 1, skipped probes: 0
WARNING: /usr/bin/staprun exited with status: 1
Pass 5: run completed in 0usr/20sys/9318real ms.
Pass 5: run failed. [man error::pass5]
test.stp
probe process("/home/user/a.out").function("func").return {
stats <<< gettimeofday_ns() - #entry(gettimeofday_ns())
}
probe end {
printf("max/avg/min: %d/%d/%d\n", #max(stats), #avg(stats), #min(stats))
print(#hist_log(stats))
}
global stats
test.c
#include <stdlib.h>
#include <unistd.h>
void func()
{
printf("Hello\n");
sleep(1);
}
int main()
{
while (1)
{
func();
}
}
systemtap does not support overlays/union filesystems. The systemtap userspace code has to be changed to get the real inode of a file if it is in overlayfs. For this the systemtap need to be code changed and built. Download systemtap source code make changes in the file uprobes-inode.c . The change is to use the d_backing_inode to find inode. Need to make changes in two places.
inode_1 = d_backing_inode(d_real((struct dentry *) dentry, NULL, 0, 0)); //use inode_1 in the following function.
if ((vm_flags & VM_EXEC) && !(vm_flags & VM_WRITE))
rc = stapiu_change_plus(target, task, addr, length,
offset, vm_flags, inode_1);
// offset, vm_flags, dentry->d_inode);
vm_file = stap_find_exe_file(mm);
if (vm_file) {
if (vm_file->f_path.dentry)
{
//inode = vm_file->f_path.dentry->d_inode;
inode = d_backing_inode(d_real((struct dentry *) vm_file->f_path.dentry, NULL, 0, 0));
}
fput(vm_file);

Linux Character device: userspace (cat) does not stop reading

I made a simple character device, and created a node for communicating with it. When I cat /dev/mychrdev, it userspace invokes my character device's read function over and over again. The relevant code is:
static ssize_t useless_read(struct file *filp, char __user *buff, size_t count, loff_t *offp) {
int ret, read_count;
read_count = sprintf(message, "Major number: %d\n", MAJOR(useless_chr_dev->cdev_num));
ret = copy_to_user(buff, message, read_count);
if (ret == 0) {
printk(KERN_INFO "userspace read success");
return read_count;
} else
return -EFAULT;
}
After I initiate a read from the terminal, dmesg is filled with:
[ 8966.299554] userspace read success
and cat is giving out lots of
Major number: 242
Major number: 242
Major number: 242
Major number: 242
Why isnt it stopping ?
cat is not about calling your read function once. cat will keep calling the read function unless you return a 0 (i.e no more bytes to read).

dmesg is not showing printk statement

I'm trying to create a proc entry.
My init_module function is as below
int init_module()
{
printk(KERN_INFO "proc2:Module Loaded\n");
proc_entry=proc_create_data(proc_name,0644,NULL,&fops,NULL);
if(proc_entry==NULL)
{
printk(KERN_INFO "proc2:Error registering proc entry");
}
else
{
printk(KERN_INFO "proc2:Proc Entry Created");
}
return 0;
}
following is cleanup method
void cleanup_module()
{
printk(KERN_INFO "proc2:module unloaded");
remove_proc_entry(proc_name,proc_entry);
}
rest of program include variable definition and callback functions.
when i compile this program it compiles well.
when i use insmod it doesn't reply me prompt.
lsmod lists my module and shows used by one (don't know what).
dmesg shows none of the above printk messages.
can you tell me what's wrong here?
Try echo "7" > /proc/sys/kernel/printk to enable all console log levels.
The numbers are corresponding to below:
#define KERN_EMERG "<0>" /* system is unusable*/
#define KERN_ALERT "<1>" /* action must be taken immediately*/
#define KERN_CRIT "<2>" /* critical conditions*/
#define KERN_ERR "<3>" /* error conditions*/
#define KERN_WARNING "<4>" /* warning conditions*/
#define KERN_NOTICE "<5>" /* normal but significant condition*/
#define KERN_INFO "<6>" /* informational*/
#define KERN_DEBUG "<7>" /* debug-level messages*/
The default number is 4, which allows console to show messages only at least in KERN_WARNING.
That's why you cannot see log in KERN_INFO level.
Even after using echo "7" > /proc/sys/kernel/printk, printk didn't worked for me.
https://lwn.net/Articles/487437/ says about modified or more enhanced version of printk called pr_** api's (pr_info,pr_emerg).
I used pr_info instead of printk and it solved my problem.
In addition to Wayne's Answer, the kernel source says
This macro expands to dynamic_pr_debug() if CONFIG_DYNAMIC_DEBUG is
set. Otherwise, if DEBUG is defined, it's equivalent to a printk with
KERN_DEBUG loglevel. If DEBUG is not defined it does nothing.
Which means you'd need to either define DEBUG or use dynamic debug.
I was able to successfully load the module with debug printk via
$ sudo insmod module-name.ko dyndbg

Resources