Kernel module periodically calling user space program - c++

I want to call a user space program from a kernel module periodically.But the kernel program is freezing the system, while I try to load it.
following is the program,
#include <linux/module.h> /* Needed by all modules */
#include <linux/kernel.h> /* Needed for KERN_INFO */
#include <linux/init.h> /* Needed for the macros */
#include <linux/jiffies.h>
#include <linux/time.h>
#include <linux/proc_fs.h>
#include <asm/uaccess.h>
#include <linux/hrtimer.h>
#include <linux/sched.h>
#include <linux/delay.h>
#define TIME_PERIOD 50000
static struct hrtimer hr_timer;
static ktime_t ktime_period_ns;
static enum hrtimer_restart timer_callback(struct hrtimer *timer){
char userprog[] = "test.sh";
char *argv[] = {userprog, "2", NULL };
char *envp[] = {"HOME=/", "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL };
printk("\n Timer is running");
hrtimer_forward_now(&hr_timer, ktime_period_ns);
printk("callmodule: %s\n", userprog);
call_usermodehelper(userprog, argv, envp, UMH_WAIT_PROC);
return HRTIMER_RESTART;
}
static int __init timer_init() {
ktime_period_ns= ktime_set( 0, TIME_PERIOD);
hrtimer_init ( &hr_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL );
hr_timer.function = timer_callback;
hrtimer_start( &hr_timer, ktime_period_ns, HRTIMER_MODE_REL );
return 0;
}
static int __exit timer_exit(){
int cancelled = hrtimer_cancel(&hr_timer);
if (cancelled)
printk(KERN_ERR "Timer is still running\n");
else
printk(KERN_ERR "Timer is cancelled\n");
}
module_init(timer_init);
module_exit(timer_exit);
MODULE_LICENSE("GPL");
test.sh is a script which just echoes a comment.
I have tested the call_usermodehelper part and timer part individually and it is working fine. But while I am combining the two codes, the system hangs.
Can anybody please help me to solve the problem.

Quick look around strongly suggests that hrtimer callbacks are executed from an irq context, which is expected - how else are you going to get high resoluton?
But this also means you must no block, while your callback can block due to call_usermodehelper regardless of NOWAIT passed.
So it seems you are testing your module on a kernel with debugging disabled, which is fundamentally wrong.
But this is less relevant as the thing you are trying to achieve in the first place looks fundamentally wrong.
I can only recommend you elaborate what is the actual problem. There is absolutely now way that forking + execing has anything to do with something requiring a high resolution timer.

Related

Debug Assertion Failed Expression __acrt_first_block == header

I have been trying to figure out why this is happening and maybe it is just due to inexperience at this point but could really use some help.
When I run my code, which is compiled into a DLL using C++20, I get that a debug assertion has failed with the expression being __acrt_first_block == header.
I narrowed down where the code is failing, but the weird part is that it runs just fine when I change the Init(std::string filePath function signature to not contain the parameter. The code is below and hope someone can help.
Logger.h
#pragma once
#include "../Core.h"
#include <memory>
#include <string>
#include "spdlog/spdlog.h"
namespace Ruby
{
class RUBY_API Logger
{
public:
static void Init(std::string filePath);
inline static std::shared_ptr<spdlog::logger>& GetCoreLogger() { return coreLogger; }
inline static std::shared_ptr<spdlog::logger>& GetClientLogger() { return clientLogger; }
private:
static std::shared_ptr<spdlog::logger> coreLogger;
static std::shared_ptr<spdlog::logger> clientLogger;
};
}
Logger.cpp
namespace Ruby
{
std::shared_ptr<spdlog::logger> Logger::coreLogger;
std::shared_ptr<spdlog::logger> Logger::clientLogger;
void Logger::Init(std::string filePath)
{
std::string pattern{ "%^[%r][%n][%l]: %v%$" };
auto fileSink = std::make_shared<spdlog::sinks::basic_file_sink_mt>(filePath, true);
// Setup the console and file sinks
std::vector<spdlog::sink_ptr> coreSinks;
coreSinks.push_back(std::make_shared<spdlog::sinks::stdout_color_sink_mt>());
coreSinks.push_back(fileSink);
// Bind the sinks to the core logger.
coreLogger = std::make_shared<spdlog::logger>("RUBY", begin(coreSinks), end(coreSinks));
// Set the Patterns for the sinks
coreLogger->sinks()[0]->set_pattern(pattern);
coreLogger->sinks()[1]->set_pattern(pattern);
// Tell spdlog to flush the file loggers on trace or worse message (can be changed if necessary).
coreLogger->flush_on(spdlog::level::trace);
// Set the default level of the logger
coreLogger->set_level(spdlog::level::trace);
// Do the same for the client logger
std::vector<spdlog::sink_ptr> clientSinks;
clientSinks.push_back(std::make_shared<spdlog::sinks::stdout_color_sink_mt>());
clientSinks.push_back(fileSink);
clientLogger = std::make_shared<spdlog::logger>("APP", begin(clientSinks), end(clientSinks));
clientLogger->sinks()[0]->set_pattern(pattern);
clientLogger->sinks()[1]->set_pattern(pattern);
clientLogger->flush_on(spdlog::level::trace);
clientLogger->set_level(spdlog::level::trace);
}
}
Entrypoint.h
#pragma once
#ifdef RB_PLATFORM_WINDOWS
extern Ruby::Application* Ruby::CreateApplication();
int main(int argc, char** argv)
{
Ruby::Logger::Init("../Logs/Recent_Run.txt");
RB_CORE_INFO("Initialized the logger.");
auto app = Ruby::CreateApplication();
app->Run();
delete app;
return 0;
}
#else
#error Ruby only supports windows
#endif // RB_PLATFORM_WINDOWS
For anyone else who runs into a similar problem, here is how I fixed it.
Essentially the function signature for the Init() function was the problem. The std::string parameter was causing the debug assertion to fire, my best guess as of right now was because of move semantics but that part I am still not sure on. So there are a couple of ways that I found to fix this.
Method 1:
Make the parameter a const char*. I don't quite like this approach as it then relies on C style strings and if you are trying to write a program in modern C++, this is a huge step backwards.
Method 2:
Make the parameter a const std::string&. Making it a const reference to a string prevents the move semantics (again as far as I know) and the assertion no longer fires. I prefer this fix as it keeps the program in modern C++.
I hope this helps anyone who has similar issues, and be careful with statics and move semantics.

Splitting ESP32 sketch into multiple threads and files

I'm working on a quite complex and large sketch for my ESP32 and I'm dividing it into threads and classes, splitting everything in different files. For sake of simplicity I'm gonna show you just the idea of my project setup.
For instance, I'm using a BME280 sensor to read temperature, humidity, and pressure values. Therefore, I created an header file called bme280.h and an associated cpp file called bme280.cpp. Here's the content of the two files.
bme280.h
#ifndef BME280_H
#define BME280_H
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#define SEALEVELPRESSURE_HPA (1013.25)
typedef struct {
float temperature;
float pressure;
float humidity;
}bmeData;
class BME280_sensor {
public:
BME280_sensor();
bmeData readBmeData();
private:
Adafruit_BME280 bme;
};
#endif
bme280.cpp
#include "bme280.h"
BME280_sensor::BME280_sensor() {
bool status;
status = bme.begin(0x76);
if (!status) {
Serial.println("Could not find a valid BME280 sensor, check wiring!");
while (1);
}
Serial.println("BME280 sensor correctly initialized!");
}
bmeData BME280_sensor::readBmeData() {
bmeData bmeValues;
bmeValues.temperature = bme.readTemperature();
bmeValues.pressure = bme.readPressure() / 100.0F;
bmeValues.humidity = bme.readHumidity();
return bmeValues;
}
This is basically how I'm using every sensor.
Now, my .ino file is busy doing some other job, so I used the pthread library for creating a different thread in charge of reading sensors values. Hence, my .ino file, before doing its job, starts this thread, which I named mainThread. Here's an example:
file.ino
#include <pthread.h>
#include "main.h"
void setup() {
delay(1000);
Serial.begin(115200);
Serial.println("Serial initialized");
pthread_t mainThreadRef;
int mainValue;
mainValue = pthread_create(&mainThreadRef, NULL, mainThread, (void*)NULL);
if (mainValue) {
Serial.println("Main thread error occured");
}
}
void loop() {
// Some other job
}
The main thread, instead, is implemented using a main.h file and a main.cpp file. Here's an example:
main.h
#ifndef MAIN_H
#define MAIN_H
#include <Arduino.h>
void *mainThread();
#endif
main.cpp
#include "main.h"
#include "bme280.h"
void *mainThread() {
BME280_sensor bme;
while (1) {
bmeData bmeValues = bme.readBmeData();
Serial.println(bmeValues.temperature);
Serial.println(bmeValues.humidity);
Serial.println(bmeValues.pressure);
delay(3000);
}
}
Now, I wonder if this whole structure of the project is good, because I'm facing weird values reading, like temperature over 100 or pressure under 0, and some other weird stuff. To be more precise:
Is it "safe" to have a thread acting as the main thread doing all the jobs?
Is it good to have a different class for each sensor that I am using or does it interfere with sensor readings?
Thank you all in advance for you help!
Is it "safe" to have a thread acting as the main thread doing all the jobs?
Yes. The thing where setup() and loop() functions get executed is also a thread. It's probably the first thread in the system, but otherwise there's no difference between it and the threads that you yourself create.
The hard part is not running an isolated process in its own thread - that's usually easy, and often a good idea. The hard part is getting data across different threads. I recommend Mastering the FreeRTOS Real Time Kernel for reading on how FreeRTOS threads (that's what the ESP32 is really using, pthreads is just a wrapper around it) work and how to communicate between them.
Is it good to have a different class for each sensor that I am using or does it interfere with sensor readings?
If you have one class per type of sensor which wraps the mundane details of how to talk to that sensor, then this is generally considered good design (encapsulation etc). But it depends, really. The devil is in the details. Note that the Arduino or Adafruit sensor libraries already do that anyway - they tend to provide a nice, simple interface that you can use without knowing the details of how it works. Don't bother wrapping those (unless you have a clear purpose).

google-coredumper returns Operation not permitted

Background: Downloaded google-coredumper-1.2.1.tar.gz from code.google.com. built the code and make install. Added library and function call to my application and execute. No core file, Logs state Operation not permitted. So I created a simple example and stepped through it and found that the library believes that the executable is already being traced. Any ideas?
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include "crashtest.h"
#include <google/coredumper.h>
#include <errno.h>
#include <string.h>
#include <signal.h>
FILE * backtrace_file = NULL;
#define SIZE 100
void CREATE_COREDUMP()
{
printf("NOTICE, Creating a core dump for debugging\n");
char extension[64];
time_t t = time((time_t*)NULL);
tm * theTime = localtime(&t);
snprintf( extension,
sizeof(extension) - 1,
"core.crashtest_02d_%02d_%02d_%02d", (theTime->tm_mday),
(theTime->tm_hour),
(theTime->tm_min) ,
(theTime->tm_sec) );
if (WriteCoreDump(extension) != 0) {
std::string errmsg(extension);
errmsg.append(" : ");
errmsg.append(strerror(errno));
printf("WARNING, Failed to create coredump: %s\n", errmsg.c_str() );
}
}
static void mysighandler(int sig)
{
printf("ERROR, Somebody Segmentation Faulted. About to Exit\n");
CREATE_COREDUMP();
exit(0);
}
crashtest::crashtest() {
char * errcond = NULL;
memcpy(errcond, "Crash This", 10);
}
crashtest::~crashtest() {}
int main(int argc, char** argv) {
struct sigaction sa;
sa.sa_flags = SA_SIGINFO;
sigemptyset(&sa.sa_mask);
sa.sa_handler = &mysighandler;
sigaction(SIGSEGV, &sa, NULL);
crashtest ct;
return 0;
}
The point of the exercise is that the main code generates a segmentation fault occasionally which does not make sense because all the values are initialized. Therefore I am trying to discover why there is a segmentation fault and would like to get a core to track down the offending line of code. I cannot just kill since the code is required to recover and continue. That is why google-coredumper is thought to be used.
According to http://www.gossamer-threads.com/lists/linux/kernel/622686, it seems that coredumper in its current state is not usable anymore:
I believe, if I interpret the data on kernel.org correctly, this
change was made by Linus and shipped with 2.6.15.
Both perftools and coredumper need to locate all threads in the active
application in order to work. As libpthread has had changing and
poorly documented APIs to get this information, and as our intent is
to support all kernel versions and all libc versions, we resorted to
ptracing any process that is suspected to be one of our threads in
order to determine if it actually is. This has the added benefit of
finding all threads (including ones not managed by libpthread) and
of temporarily suspending them, so that we have a stable memory image
that we can inspect. Think of both tools as something like a
lightweight in-process debugger.
Obviously, special care has to be taken to not ptrace our own thread,
and to avoid any library calls that could deadlock.
Before the patch, attaching ptrace to my own threads was a valid
operation. With this new patch, I can no longer do that.

Catch.hpp unit testing: How to dynamically create test cases?

I am using CATCH v1.1 build 14 to do unit testing of my C++ code.
As part of the testing, I would like to check the outputs of several modules in my code. There is not a set number of modules; more modules may be added at any time. However, the code to test each module is identical. Therefore, I think it would be ideal to put the testing code in a for loop. In fact, using catch.hpp, I have verified that I can dynamically create Sections within a Test Case, where each Section corresponds to a module. I can do this by enclosing the SECTION macro in a for loop, for example:
#include "catch.hpp"
#include <vector>
#include <string>
#include "myHeader.h"
TEST_CASE("Module testing", "[module]") {
myNamespace::myManagerClass manager;
std::vector<std::string> modList;
size_t n;
modList = manager.getModules();
for (n = 0; n < modList.size(); n++) {
SECTION(modList[n].c_str()) {
REQUIRE(/*insert testing code here*/);
}
}
}
(This is not a complete working example, but you get the idea.)
Here is my dilemma. I would like to test the modules independently, such that if one module fails, it will continue testing the other modules instead of aborting the test. However, the way CATCH works, it will abort the entire Test Case if a single REQUIRE fails. For this reason, I would like to create a separate Test Case for each module, not just a separate Section. I tried putting my for loop outside the TEST_CASE macro, but this code fails to compile (as I expected):
#include "catch.hpp"
#include <vector>
#include <string>
#include "myHeader.h"
myNamespace::myManagerClass manager;
std::vector<std::string> modList;
size_t n;
modList = manager.getModules();
for (n = 0; n < modList.size(); n++) {
TEST_CASE("Module testing", "[module]") {
SECTION(modList[n].c_str()) {
REQUIRE(/*insert testing code here*/);
}
}
}
It might be possible to do this by writing my own main(), but I can't see how to do it exactly. (Would I put my TEST_CASE code directly into the main()? What if I want to keep my TEST_CASE code in a different file? Also, would it affect my other, more standard Test Cases?)
I can also use CHECK macros instead of REQUIRE macros to avoid aborting the Test Case when a module fails, but then I get the opposite problem: It tries to continue the test on a module that should have failed out early on. If I could just put each module in its own Test Case, that should give me the ideal behavior.
Is there a simple way to dynamically create Test Cases in CATCH? If so, can you give me an example of how to do it? I read through the CATCH documentation and searched online, but I couldn't find any indication of how to do this.
There is a way to achieve what you're looking for, but I'd observe that you're going about this the wrong way:-
Unit tests are to meant to test each unit, i.e. you write a component and a test to verify the correct behaviour of that component. If you later decide to change one component in some way, you update the corresponding test.
If you aggregate all of your tests for all of your components into the same file, it becomes much harder to isolate the unit that behaves differently.
If you want to factor out the testing of a component because it's essentially the same across all your components, you could do one of the following:
1. Extract the common tests to a separate header file
You can #define the type name of the component you wish to test and then include a header file with all the tests in it:
// CommonTests.t.h
#include "catch.hpp"
TEST_CASE("Object Can be instantiated", "[ctor]")
{
REQUIRE_NOTHROW(COMPONENT component);
}
// SimpleComponent.t.cpp
#define COMPONENT SimpleComponent
#include "CommonTests.t.h"
This is straightforward to do, but has a downside - when you run the test runner, you'll have duplicate tests (by name) so you can only run all tests, or by tag.
You can solve this by stringizing the component name and pre/appending it to the test case name.
** 2. Call common tests by parameterising the component **
Put your common tests into a separate file and call the common test methods directly:
// CommonTests.t.h
void RunCommonTests(ComponentInterface& itf);
// CommonTests.t.cpp
void RunCommonTests(ComponentInterface& itf)
{
REQUIRE(itf.answerToLifeUniverseAndEverything() == 42);
}
// SimpleComponent.t.cpp
#include "SimpleComponent.h"
#include "CommonTest.t.h"
#include "catch.hpp"
TEST_CASE("SimpleComponent is default-constructible", "[ctor]")
{
REQUIRE_NOTHROW(SimpleComponent sc);
}
TEST_CASE("SimpleComponent behaves like common components", "[common]")
{
SimpleComponent sc;
RunCommonTests(sc);
}
It sounds like Catch might be migrating toward property-based testing, which I'm hoping will allow a way to dynamically create test cases. In the meantime, here's what I ended up doing.
I created a .cpp file with a single TEST_CASE for a single module, and a global variable for the module name. (Yes, I know global variables are evil, which is why I am being careful and using it as the last resort):
module_unit_test.cpp:
#include "catch.hpp"
#include <string>
#include "myHeader.h"
extern const std::string g_ModuleName; // global variable: module name
TEST_CASE("Module testing", "[module]") {
myNamespace::myManagerClass manager;
myNamespace::myModuleClass *pModule;
SECTION(g_ModuleName.c_str()) {
pModule = manager.createModule(g_ModuleName.c_str());
REQUIRE(pModule != 0);
/*insert more testing code here*/
}
}
Then, I create an executable that will run this test on a single module specified on the command line. (I tried looping through the Catch::Session().run() below, but Catch does not allow it to run more than once.) The object file from the code below module_test.cpp and from the unit test code above module_unit_test.cpp are linked when creating the executable.
module_test.cpp:
#define CATCH_CONFIG_RUNNER
#include "catch.hpp"
#include <string>
#include <cstdio>
std::string g_ModuleName; // global variable: module name
int main(int argc, char* argv[]) {
// Make sure the user specified a module name.
if (argc < 2) {
std::cout << argv[0] << " <module name> <Catch options>" << std::endl;
return 1;
}
size_t n;
char* catch_argv[argc-1];
int result;
// Modify the input arguments for the Catch Session.
// (Remove the module name, which is only used by this program.)
catch_argv[0] = argv[0];
for (n = 2; n < argc; n++) {
catch_argv[n-1] = argv[n];
}
// Set the value of the global variable.
g_ModuleName = argv[1];
// Run the test with the modified command line arguments.
result = Catch::Session().run(argc-1, catch_argv);
return result;
}
Then, I do the looping in a separate executable (not linked to the object files from the code above):
module_test_all.cpp:
#include <cstdlib>
#include <vector>
#include <string>
#include "myHeader.h"
int main(int argc, char* argv[]) {
std::string commandStr;
int result, status = 0;
myNamespace::myManagerClass manager;
std::vector<std::string> modList;
size_t m, n;
// Scan for modules.
modList = manager.getModules();
// Loop through the module list.
for (n = 0; n < modList.size(); n++) {
// Build the command line.
commandStr = "module_test " + modList[n];
for (m = 1; m < argc; m++) {
commandStr += " ";
commandStr += argv[m];
}
// Do a system call to the first executable.
result = system(commandStr.c_str());
// If a test fails, I keep track of the status but continue
// looping so all the modules get tested.
status = status ? status : result;
}
return status;
}
Yes, it is ugly, but I have confirmed that it works.

translate_address in c++\linux

i am trying to make user threads in C++, so while trying to initialize them i am getting a compiler error :translate_address was not declared in this scope
#include <iostream>
#include <cstdlib>
#include <csignal>
#include <csetjmp>
#define JB_SP 6 //Location in the code
#define JB_PC 7 //Stack pointer
#define STACK_SIZE 10
typedef unsigned long address_t; //64bit address
sigjmp_buf jbuf[3];
char stack1[STACK_SIZE];
void f(){
}
void setup(){
unsigned int sp, pc;
sp = (address_t)stack1 + STACK_SIZE - sizeof(address_t);
pc = (address_t)f;
sigsetjmp(jbuf[0],1);
(jbuf[0]->__jmpbuf)[JB_SP] = translate_address(sp);
(jbuf[0]->__jmpbuf)[JB_PC] = translate_address(pc);
sigemptyset(&jbuf[0]->__saved_mask);//empty saved signal mask
}
int main(){
return 1;
}
am i meant to include it some how? or is there a different problem?
thank you.
translate_address is not a Linux function. If you're referring to some kind of book or example code, it should explain where you're supposed to get this function from. If it doesn't, chances are it's not meant for Linux (or is a really, really bad reference/example).
Furthermore, you should NOT modify the contents of jmp_buf or sigjmp_buf directly. These are architecture and platform-dependent structures, and only the C library is allowed to mess with them. Since the contents of the structures are OS-dependent, if you're using a reference intended for some other OS when modifying sigjmp_buf, Bad Things will happen.
You should instead either use setcontext, getcontext, and makecontext for user threads (fibers) or pthread_create for OS-level threads.