What is the scope of pr_cont in linux kernel? - linux-kernel

I read about pr_cont() in the documentation here but still not clear. The documentation says that it :
Continues a previous log message in the same line.
As expected, for the below code I get the following output.
void another_func(void)
{
printk(KERN_INFO "This is another function\n");
pr_cont(KERN_INFO "Testing\n");
}
OUTPUT :
[ 830.463883] This is another function
[ 830.463903] Testing
But what is the scope of "previous message" here ? Will it append to any dmesg log preceding it, no matter where that previous dmesg came from?

This usage is incorrect:
void another_func(void)
{
printk(KERN_INFO "This is another function\n");
pr_cont(KERN_INFO "Testing\n");
}
pr_cont(KERN_INFO "Testing\n"); should be pr_cont("Testing\n"); and is equivalent to printk(KERN_CONT "Testing\n");.
The KERN_CONT tag only continues the previous log message if the previous log message does not end with a newline ('\n'). Otherwise it begins a new log message with the KERN_DEFAULT log level.
Here is an example of correct usage:
void another_func(void)
{
printk(KERN_INFO "This is another function... ");
pr_cont("Testing\n"); /* or: printk(KERN_CONT "Testing\n"); */
}
Normally, the two function calls will produce a single log message with at the INFO log-level: This is another function... Testing. However, if another printk call (without KERN_CONT) manages to sneak inbetween, the first log message will be finalized with a newline.
This another_func():
void sneaky(void);
void another_func(void)
{
printk(KERN_INFO "First message... ");
sneaky(); /* Could be called during preemption for example. */
printk(KERN_CONT "Continued first\n");
}
void sneaky(void)
{
printk(KERN_INFO "Sneaky\n");
}
produces these three messages:
First message ...
Sneaky
Continued first
Even sneakier, this another_func():
void sneakier(void);
void another_func(void)
{
printk(KERN_INFO "First message... ");
sneakier(); /* Could be called during preemption for example. */
printk(KERN_CONT "Continued first\n");
}
void sneakier(void)
{
printk(KERN_INFO "Sneaky ... ");
}
produces these two messages with the wrong message continued:
First message ...
Sneaky ... Continued first

Related

How to print stacktrace once an exception is thrown before the catch block (stack unwinding)

Let's say we have the following code:
#include <exception>
void funcA() {
funcB();
}
void funcB() {
funcC();
}
void funcC() {
funcD();
}
void funcD() {
throw std::runtime_error("Exception!!"); //3
}
void funcE() {
int * p;
delete p; //4
}
int main (int argc, char **argv) {
try {
funcA(); //1
} catch (std::exception exc) {
std::cerr << exc.what() << endl; //2
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
I want to print the stack trace with the line number of the thrown exception in a multi-threaded efficient way.
I've been checking the last couple of days the solutions and approaches people are doing but unfortunately nothing was useful in my case. I can use for example the boost library boost::stacktrace::stacktrace() in //2 or any other library but the problem here is I have to catch the exception to do this and this approach is not efficient if your code has hundreds of nested functions. You can't just go over all of them and wrap each one with try-catch and handle them separately.
So basically what I need to do is if an exception is thrown at //3 I should be able to print the stack trace of the exception in `//2
I'm aware of the stack unwinding and how it works, but as far as I understand whenever your code reaches the catch block this means that the exception stack has been unwinded and you can't get it. Please correct me if I'm wrong!
Is there a way at least to add something similar to middleware before unwinding the exception stack? Or do I have to do it manually?
Edit:
Also, what would happen when I can funcE() is a memory access exception but this exception is never caught. Is there a way to catch such kind of exceptions or at least print its stack trace before the crash?
Note:
I'm running my code on Linux and macOS, C++11 with Silicon web framework.
It's a big system so I'm trying to achieve some logging mechanism that can be used across the system.
I'm posting this in case anyone came across the same question and wanted a quick useful answer.
I've ended up overriding the main C++ throw exception behavior using this gist
I've changed a few things in the __cxa_throw function to tackle my own issue and used boost::stacktrace to get a more human-readable stack trace.

Statistics collection related values do not increase in OMNeT++

In order to measure the packet transmission/reception count, I declared a scalar variable and wrote a function related to record. It looks like this:
A.h
class VEINS_API A : public DemoBaseApplLayer
{
private:
long StaticsFrsaPacketCount;
cOutVector frsaPacketCountVector;
...
}
A.cc
void A::initialize(int stage)
{
DemoBaseApplLayer::initialize(stage);
if(stage == 0)
{
StaticsFrsaPacketCount = 0;
frsaPacketCountVector.setName("fR_SA packet count");
...
}
}
void A::finish()
{
recordScalar("fR_SA Packet", StaticsFrsaPacketCount);
...
}
void A::handleSelfMsg(cMessage* msg)
{
switch(msg -> getKind())
{
case SEND_FRSA_EVT:
{
...
StaticsFrsaPacketCount++;
frsaPacketCountVector.record(StaticsFrsaPacketCount);
...
sendDelayedDown(wsm, uniform(0.01, 0.50));
}
...
}
}
I wrote the code by referring to the statistics written in the official OMNeT++ Tictoc tutorial. However, the result of the scalar value through the generated .anf file after the simulation is finished is as shown in the image below.
In other words, it seems that the value is incremented 1 time and not incremented after that. What is the cause?
(this part) of your code looks fine. The most likely reason why you have 1 in the result because really just one packet was sent. The statistics are showing what is actually happening. If you expect several packets to be sent, I suggest to start the app in Qtenv and step over the simulation and make sure that it works as you expect.

exit() method entered without exit command

I have Processing 3 code that is exhibiting some odd behavior. I have a void exit() method defined that is being executed at random times without the user actually telling the code to exit. Here is the method:
void exit()
{
println("clearing buffer and closing file");
if (output != null) {
print("output is not null");
try {
output.close();
}
catch (IOException e) {
println("Error while closing the writer");
}
}
super.exit();
}
As you can see, the only thing that it does is attempt to close a buffered writer called output. Flushing this writer is not critical, so for now I am just removing it from my sketch. But long term, I am curious how this can be happening. Nowhere else in my code is the exit method explicitly called. IE, the code cannot decide to exit. It is only when the user closes the problem using the X.
Note: I cannot upload the entire code this method is attached too because it is too long. I think perhaps a better way to phrase my questions would be something like:
"Hi, I am a noob that doesn't know anything about the exit method. Is there anyway that this method could somehow get called without me explicitly calling it or hitting the exit button?"
Add this at the beginning of your exit() method.
new Exception().printStackTrace();
The resulting stacktrace should allow you to figure out what is calling your exit() method.
Or if you can't tweak the code, you can run the application using a debugger and set a breakpoint at the start of the exit() method.
To answer your question about whether it is possible, the answer depends on what you mean by "without me explicitly calling". There are various ways to call a method, some of which are quite obscure; e.g.
You can use reflection to get the Method object for the exit method from the declaring class, and then call invoke(...) on it.
You can call a Java method from native code via the JNI or JNA apis.
You can generate Java source code that contains an exit() call, compile it, load it, and run it.
You can insert an exit() call into an "innocent" method using BCEL or similar.
And ...
If there is a debug agent attached to the JVM, the debugger can call exit() on some thread in the JVM.
In short, the answer to your question is Yes.
Your method could be found and invoked dynamically using reflection by any class in the same classloader or any other that is below in the hierarchy.
Also, it has a default access. So it could be invoked statically by any class in the same package.
+1 for #Andres, reflection is one possibility.
Have you tried using a breakpoint on the method and looking at the thread's stacktrace?
Personally I don't use breakpoints (just my style) and would try and look at the thread programmatically. Maybe some of the following code can help you look at the thread and get an idea of what's going on:
public class ThreadUtil {
/** Blocked constructor **/
private ThreadUtil() {
}
/**
* Get the stackstrace of the current {#link Thread}.
* The stacktrace will be returned in the form of a string.
*/
public static String getStackTrace() {
return getStackTrace(Thread.currentThread());
}
/**
* Get the stackstrace of a {#link Thread}.
* The stacktrace will be returned in the form of a string.
*/
public static String getStackTrace(Thread thread) {
StringBuilder sb = new StringBuilder();
StackTraceElement[] currThreadStackTraceElementList = thread.getStackTrace();
appendStackTrace(sb, currThreadStackTraceElementList);
return sb.toString();
}
public static String getAllStackTraces() {
StringBuilder sb = new StringBuilder();
Map<Thread, StackTraceElement[]> threadList = Thread.getAllStackTraces();
for (StackTraceElement[] currThreadStackTraceElementList : threadList.values()) {
appendStackTrace(sb, currThreadStackTraceElementList);
}
return sb.toString();
}
private static void appendStackTrace(StringBuilder sb,
StackTraceElement[] currThreadStackTraceElementList) {
sb.append("Thread stack trace: \n");
for (StackTraceElement currThreadStackTraceElement : currThreadStackTraceElementList) {
sb.append("\t" + currThreadStackTraceElement + "\n");
}
sb.append("\n");
}
}
It's a Processing-specific thing.
void exit() is a method already defined by processing in PApplet.java
As explained in the reference:
Rather than terminating immediately, exit() will cause the sketch to
exit after draw() has completed (or after setup() completes if called
during the setup() function).
For Java programmers, this is not the same as System.exit(). Further,
System.exit() should not be used because closing out an application
while draw() is running may cause a crash (particularly with P3D).
exit() it is expected to be used something like this:
void draw() {
line(mouseX, mouseY, 50, 50);
}
void mousePressed() {
exit();
}
It is called within PApplet.java in a few places, notably in handleKeyEvent to close the sketch when ESC is pressed, or when ⌘w is pressed.
Just rename your method to something other than exit()

Suppress error message at DoDataExchange

I want to suppress the MFC error message on data validation:
void CMotorView::DoDataExchange(CDataExchange* pDX)
{
DDX_Text(pDX, IDC_AMBIENTTEMP, m_pSet->m_AmbientTemp);
}
If the text in editcontrol IDC_AMBIENTTEMP is non numeric on saving data to variables, the framework will show a messagebox prompting the user to enter a number. I want to suppress this message, and handle the error in my own code.
I assumed the framework will throw an exception in case of validation error, but this appears not to be the case. Neither does DDX_Text return a value What am I doing wrong?
void CMotorView::DoDataExchange(CDataExchange* pDX)
{
try
{
DDX_Text(pDX, IDC_AMBIENTTEMP, m_pSet->m_AmbientTemp);
}
catch(CUserException* ex)
{
// nothing caught here
}
catch(...)
{
// nothing caught here either
}
}
In case of an error DDX_Text first displays an error dialog, then it throws an exception. You can catch this with catch(CUserException *e). Please note that a pointer is thrown!
I'd suggest that you either DDX_Text to a string. This does not fail and you can then check if the string is really a number. Or you can write your own DDX_TextMyFn to do what you want. You can use the MFC original function as a base implementation.
Set ES_NUMBER as a style for the edit control. This will reduce errors user can make.
The message boxes inside the DDX routines can't be suppressed or redirected.
Here is some pseudocode that uses a class CEditInt that has a member unction GetValue/SetValue.
You can also write a DDX_EditInt routine that works on a CEdit control and use Get/SetDlgItemInt.
void AFXAPI DDX_EditInt(CDataExchange* pDX, int nIDC, int &iValue)
{
// Get pointer to control
HWND hWndCtrl = pDX->PrepareEditCtrl(nIDC);
CEditInt *pWnd = (CEditInt *)CWnd::FromHandle(hWndCtrl);
// Must be an CEditInt
ASSERT(pWnd->IsKindOf(RUNTIME_CLASS(CEditInt)));
// get the information from the defined window
if (pDX->m_bSaveAndValidate)
// Get the Value
iValue = pWnd->GetValue();
else
pWnd->SetValue(iValue);
}

Handlemessage(cMessage *msg) is not properly scheduled

This is an example of omnet++ manual in chapter 4 , article 4.10.
Inside the handleMessage method the msg is not properly scheduled, I guess. In case FSM_Exit(active): state the error message shown. But how could the message be other than startstopburst and sendmessage?
void wirelessnode::handleMessage(cMessage *msg)
{
FSM_Switch(fsm)
{
case FSM_Exit(init):
FSM_Goto(fsm,sleep);
break;
case FSM_Enter(sleep):
scheduleAt(simTime()+exponential(sleepTimeMean),startstop);
break;
case FSM_Exit(sleep):
scheduleAt(simTime()+exponential(burstTimeMean),startstop);
if(msg!=startstop)
{
error("Invalid event in state ACTIVE in FSM_Exit(sleep) state ");
}
FSM_Goto(fsm,active);
break;
case FSM_Enter(active):
scheduleAt(simTime()+exponential(sendIATime),sendmsg);
break;
case FSM_Exit(active):
if(msg==sendmsg)
{
FSM_Goto(fsm,snd);
}
else if(msg==startstop)
{
cancelEvent(sendmsg);
FSM_Goto(fsm,sleep);
}
else
{
error("invalid event in state ACTIVE in FSM_Exit(active) state ");
//FSM_Goto(fsm,active);
}
break;
case FSM_Exit(snd):
{
char msgname[32];
sprintf(msgname,"job-%d",++i);
ev <<"Generating"<< msgname <<endl;
cMessage *job=new cMessage(msgname);
// job->SetBitLength ( (long) *msglength );
job->setTimestamp();
int gateCount=this->gateSize("radioInOut$o");
int d=intrand(gateCount);
send(job,"radioInOut$o",d);
FSM_Goto(fsm,active);
break;
}
}
}
The fact that the code considers an event other than startstopburst and sendmessage, does not necessarily mean that there is another event, but there could be one.
In general, in a finite state machine you would like to consider all of the allowed and disallowed cases to avoid any undefined behavior. And what you see in the code is probably a measure against that.
On another note, if you view it in terms of coding -- whenever you have a if you better have an else
From the Wikipedia article about Finite-State Machine:
... It is conceived as an abstract machine that can be in one of a
finite number of states.
This means that all of the possible states should be defined (i.e. at any time the program must be in a well-defined state).

Resources