I have created a class in a Finite Element Method code in C++. I am using AppleClang 8.0.0.8000042.
One method in my class is fairly large, over 45k lines (after indenting it. Before, i.e., line breaks only after ; and }, it was around 1.5k). I know this is bad practice, but for now I don't really see other option for what I am doing in this method.
The first instruction in this method calls another method for the same class. When I run it in serial mode (The framework I am developing in has multi-threading support) I have no problems. However, if I use the multi-thread mode(on the same computer), even with only 1 thread, I get a EXC_BAD_ACCESS (code = 1, address=0x6ffffffa3280).
Ok, I thought I had messed up somewhere else. When I ran out of options I decided to just erase most of my colossal method, turning it into a useless but short method with just that instruction that would cause me the EXC_BAD_ACCESS error. However, it did solve the problem.
The situation is something like this:
Bad scenario
//A.cpp
int A::foo() const{ return 2;}
void A::fun(const double & in_param){
double out;
this->func(in_param, out);
...
}
void A::func(const double& in_param, double &out_param){
const int fooVar = this->foo();//EXC_BAD_ACCESS
...
(45k lines of code)
...
}
Good scenario
//A.cpp
int A::foo() const{ return 2;}
void A::fun(const double & in_param){
double out;
this->func(in_param, out);
...
}
void A::func(const double& in_param, double &out_param){
const int fooVar = this->foo();//fooVar = 2
}
Would anyone know why does this happen? And why does it happen only when multithreading?
I swear I will try to think on a way to reduce the length of the method, but I am quite curious on why I got that error.
Related
I have been working on this simply hobbyist OS, and I have decided to add some C++ support. Here is the simple script I wrote. When I compile it, I get this message:
cp.o: In function `caller':
test.cpp:(.text+0x3a): undefined reference to `__stack_chk_fail'
Here is the script:
class CPP {
public:
int a;
void test(void);
};
void CPP::test(void) {
// Code here
}
int caller() {
CPP caller;
caller.test();
return CPP.a;
}
Try it like this.
class CPP {
public:
int a;
void test(void);
};
void CPP::test(void) {
CPP::a = 4;
}
int caller() {
CPP caller;
caller.test();
return caller.a;
}
int main(){
int called = caller();
std::cout << called << std::endl;
return 0;
}
It seems to me that the linker you are using can't find the library containing a security function crashing the program upon detecting stack smashing. (It may be that the compiler doesn't include the function declaration for some reason? I am not familiar who actually defies this specific function.) Try compiling with -fno-stack-protector or equivalent.
What is the compiler used? A workaround might be defining the function as something like exit(1); or similar. That would produce the intended effect yet fix the problem for now.
I created a test program to show how this actually plays out. Test program:
int main(){
int a[50]; // To have the compiler manage the stack
return 0;
}
With only -O0 as the flag ghidra decompiles this to:
undefined8 main(void){
long in_FS_OFFSET;
if (*(long *)(in_FS_OFFSET + 0x28) != *(long *)(in_FS_OFFSET + 0x28)) {
/* WARNING: Subroutine does not return */
__stack_chk_fail();
}
return 0;
}
With -fno-stack-protector:
undefined8 main(void){
return 0;
}
The array was thrown out by ghidra in decompilation, but we see that the stack protection is missing if you use the flag. There are also some messed up parts of this in ghidra (e.g. int->undefined8), but this is standard in decompilation.
Consequences of using the flag
Compiling without stack protection is not good per se, but it shouldn't affect you in much. If you write some code (that the compiler shouts you about) you can create a buffer overflowable program, which should not be that big of an issue in my optinion.
Alternative
Alternatively have a look at this. They are talking about embedded systems, but the topic seems appropriate.
Why is the code there
Look up stack smashing, but to my knowledge I will try to explain. When the program enters a function (main in this case) it stores the location of the next instruction in the stack.
If you write an OS you probably know what the stack is, but for completeness: The stack is just some memory onto which you can push and off which you can pop data. You always pop the last pushed thing off the stack. C++ and other languages also use the stack as a way to store local variables. The stack is at the end of memory and when you push something, the new thing will be further forward rather than back, it fills up 'backwards'.
You can initialise buffers as a local variable e.g. char[20]. If you filled the buffer without checking the length you might overfill this, and overwrite things in the stack other than the buffer. The return address of the next instruction is in the stack as well. So if we have a program like this:
int test(){
int a;
char buffer[20];
int c;
// someCode;
}
Then the stack will look something like this at someCode:
[ Unused space, c, buffer[0], buffer[1] ..., buffer[19], a, Return Address, variables of calling function ]
Now if I filled the buffer without checking the length I can overwrite a (which is a problem as I can modify how the program runs) or even the return address (which is a major flaw as I might be able to execute malicious shellcode, by injecting it into the buffer). To avoid this compilers insert a 'stack cookie' between a and the return address. If that variable is changed then the program should terminate before calling return, and that is what __stack_chk_fail() is for. It seems that it is defined in some library as well so you might not be able use this, despite technically the compiler being the one that uses this.
I wrote the following MBED-based C++ program as an experiment for a more detailed project I am working on for my Nucleoboard Microcontroller:
#include "mbed.h"
DigitalOut greenLed(PA_5);
#include "mbed.h"
class TimedLED
{
public:
TimedLED()
{
Ticker t;
t.attach_us(this, &TimedLED::flip, 1000000);
}
void flip(void)
{
static int count = 0;
greenLed.write(count%2); //-- toggle greenLed
count++;
}
};
int main()
{
TimedLED flash;
while (1);
}
All the references I looked at seemed to indicate that t.attach_us(this, &TimedLED::flip, 1000000) should call the method, 'flip' every second and so cause the LED to toggle on and off. This is not happening, however. I cannot see what the problem is. I hope someone can help me clear this up.
I am getting the following warning message indicating that this format is deprecated, but the link to the documentation was broken, so I couldn't get more details:
Function "mbed::Ticker::attach_us(T *, M, us_timestamp_t) [with T=TimedLED, M=void(TimedLED::*)()]" (declared at /extras/mbed_fd96258d940d/drivers/Ticker.h:122) was declared "deprecated" "t.attach_us(this, &TimedLED::flip, 1000000);"
Even if it is deprecated, it still should work, shouldn't it? Also, presumably if the deprecation message is correct, there is a newer way to do the same thing. I can't find reference to an alternative method though anywhere.
You declare Ticker t; in your constructor on the stack, when the constructor exits it will clear the object, and thus the code will not run.
Declare the variable in your class, and it'll run as expected:
class TimedLED
{
public:
TimedLED()
{
t.attach(callback(this, &TimedLED::flip), 1.0f);
}
void flip(void)
{
static int count = 0;
greenLed.write(count%2); //-- toggle greenLed
count++;
}
private:
Ticker t;
};
Also note the change in the constructor, this is the prefered (non-deprecated) way to attach callbacks in mbed OS 5.
Tried to simplify the situation as much as possible. So I have a class:
class C
{
int * field;
public:
C() : field(nullptr) {}
void init(int* f) { field = f; }
int getI1() { return *field; }
int getI2() { return *field; }
};
which generates 2 Lint warnings 613 (Possible use of null pointer 'C::i'...)
I know that "field" won't be null when getI1() or getI2() are called. And unfortunately I cannot initialize it in constructor. So I want to suppress Lint warnings. I can do it like this
class C
{
int * field;
public:
C() : field(nullptr) {}
void init(int* f) { field = f; }
int getI1() { return *field; } //lint !e613
int getI2() { return *field; } //lint !e613
};
but in my real case:
1) There are rather many such classes and each class has many
functions that use this pointer.
2) My managements doesn't allow me to add too many lint
comments in the code.
So my question: does anyone know a command-line option that will let me tell Lint "I know the code is not best, just stop checking this particular member variable for null"?
Something similar to -sem parameter, maybe?
So my question: does anyone know a command-line option that will let me tell Lint "I know the code is not best, just stop checking this particular member variable for null"?
That's the wrong way to handle it (even if I knew such command line parameter).
PC-Lint warns you correctly about that
int getI1() { return *i; } //lint !e613
int getI2() { return *i; } //lint !e613
may unintentionally dereference a nullptr.
Just trying to suppress1 that waning isn't a very good idea, since the call of the init() function isn't mandatory.
The correct way to get rid of it is to add an explicit check like
int getI1() {
if(i) {
return *i;
}
throw std::runtime_error("i wasn't initialized properly.");
}
1) There are rather many such classes and each class has many functions that use this pointer.
There's no other way than just wading through them and refactor that bad code.
2) My managements doesn't allow me to add too many lint comments in the code.
That's a good policy. They spent the money to install the SCA tool for reasons, and want the code being improved.
If that collides with the time you've got available doing so, ask them to establish a task that allows you to accomplish that.
If you just want to concentrate on other (more important stuff) reported by PC-Lint, use grep or alike tools to filter out what you don't want to see ATM. But don't establish a command line parameters to suppress them completely. That are things that will be forgotten forever and never be touched or approached at later stages again.
1
Suppressing any errors or warnings given by a SCA tool like PC-Lint defeats the whole purpose of it, unless you're absolutely sure the tool gives you a false positive. Otherwise your company could simply save the money spent for the licenses, and stick to the bad coding habits.
It seems that after the constructor has run, you have an instance that is not usable (will crash if you call getT1() or getT2()). That's not something that I like at all.
Much better to have a constructor C(int* f). Problem goes away. This is a case where the warning is entirely justified and warns you of bad code, so the bad code should be fixed.
I know that code is bad, should be fixed and so on. Unfortunately I cannot do it right now (because of huge amount of effort for one person and highly risky changes), but those errors were overwhelming other, sometimes more critical, problems
I found out that to suppress this warning in one line you can do:
-esym(613, C::field)
I have several configuration flags that I am implementing as structs. I create an object. I call a method of the object with a flag, which eventually triggers a comparison between two flags. However, by this time, one of the flags has been overwritten somehow.
To clarify, here's a VERY simplified version of the code that should illustrate what I'm seeing:
class flag_type { unsigned int flag; /*more stuff*/ };
flag_type FLAG1
flag_type FLAG2
class MyObject {
public:
void method1(const flag_type& flag_arg) {
//conditionals, and then:
const flag_type flag_args[2] = {flag_arg,flag_arg};
method2(flag_args);
}
void method2(const flag_type flag_args[2]) {
//conditionals, and then:
method3(flag_args[0]);
}
void method3(const flag_type& flag_arg) { //Actually in a superclass
//stuff
if (flag_arg==FLAG1) { /*stuff*/ }
//stuff
}
};
int main(int argc, const char* argv[]) {
//In some functions called by main:
MyObject* obj = new MyObject();
//Later in some other functions:
obj->method1(FLAG1);
}
With a debugger and print statements, I can confirm that both FLAG1 and flag_arg/flag_args are fine in both "method1" and "method2". However, when I get to method3, "FLAG1.flag" has been corrupted, so the comparison fails.
Now, although I'm usually stellar about not doing it, and it passes MSVC's static code analysis on strictest settings, this to me looks like the behavior of a buffer overrun.
I haven't found any such error by looking, but of course one usually doesn't. My question isA: Am I screwing up somewhere else? I realize I'm not sharing any real code, but am I missing something already? This scheme worked before before I rewrote a large portion of the code.
B: Is there an easier way than picking through the code more carefully until I find it? The code is cross-platform, so I'm already setting it up to check with Valgrind on an Ubuntu box.
Thanks to those who tried to help. Though, it should be noted that the code was for clarification purposes only; I typed it from scratch to show generally was was happening; not to compile. In retrospect, I realize it wasn't fair to ask people to solve it on so little information--though my actual question "Is there an easier way than picking through the code more carefully" didn't really concern actually solving the problem--just how to approach it.
As to this question, on Ubuntu Linux, I got "stack smashing" which told me more or less where the problem occurred. Interestingly, the traceback for stack smashing was the most helpful. Long story short, it was an embarrassingly basic error; strcpy was overflowing (in the operators for ~, | and &, the flags have a debug string set this way). At least it wasn't me who wrote that code. Always use strncpy, people :P
I have a setup that looks like this.
class Checker
{ // member data
Results m_results; // see below
public:
bool Check();
private:
bool Check1();
bool Check2();
// .. so on
};
Checker is a class that performs lengthy check computations for engineering analysis. Each type of check has a resultant double that the checker stores. (see below)
bool Checker::Check()
{ // initilisations etc.
Check1();
Check2();
// ... so on
}
A typical Check function would look like this:
bool Checker::Check1()
{ double result;
// lots of code
m_results.SetCheck1Result(result);
}
And the results class looks something like this:
class Results
{ double m_check1Result;
double m_check2Result;
// ...
public:
void SetCheck1Result(double d);
double GetOverallResult()
{ return max(m_check1Result, m_check2Result, ...); }
};
Note: all code is oversimplified.
The Checker and Result classes were initially written to perform all checks and return an overall double result. There is now a new requirement where I only need to know if any of the results exceeds 1. If it does, subsequent checks need not be carried out(it's an optimisation). To achieve this, I could either:
Modify every CheckN function to keep check for result and return. The parent Check function would keep checking m_results. OR
In the Results::SetCheckNResults(), throw an exception if the value exceeds 1 and catch it at the end of Checker::Check().
The first is tedious, error prone and sub-optimal because every CheckN function further branches out into sub-checks etc.
The second is non-intrusive and quick. One disadvantage is I can think of is that the Checker code may not necessarily be exception-safe(although there is no other exception being thrown anywhere else). Is there anything else that's obvious that I'm overlooking? What about the cost of throwing exceptions and stack unwinding?
Is there a better 3rd option?
I don't think this is a good idea. Exceptions should be limited to, well, exceptional situations. Yours is a question of normal control flow.
It seems you could very well move all the redundant code dealing with the result out of the checks and into the calling function. The resulting code would be cleaner and probably much easier to understand than non-exceptional exceptions.
Change your CheckX() functions to return the double they produce and leave dealing with the result to the caller. The caller can more easily do this in a way that doesn't involve redundancy.
If you want to be really fancy, put those functions into an array of function pointers and iterate over that. Then the code for dealing with the results would all be in a loop. Something like:
bool Checker::Check()
{
for( std::size_t id=0; idx<sizeof(check_tbl)/sizeof(check_tbl[0]); ++idx ) {
double result = check_tbl[idx]();
if( result > 1 )
return false; // or whichever way your logic is (an enum might be better)
}
return true;
}
Edit: I had overlooked that you need to call any of N SetCheckResultX() functions, too, which would be impossible to incorporate into my sample code. So either you can shoehorn this into an array, too, (change them to SetCheckResult(std::size_t idx, double result)) or you would have to have two function pointers in each table entry:
struct check_tbl_entry {
check_fnc_t checker;
set_result_fnc_t setter;
};
check_tbl_entry check_tbl[] = { { &Checker::Check1, &Checker::SetCheck1Result }
, { &Checker::Check2, &Checker::SetCheck2Result }
// ...
};
bool Checker::Check()
{
for( std::size_t id=0; idx<sizeof(check_tbl)/sizeof(check_tbl[0]); ++idx ) {
double result = check_tbl[idx].checker();
check_tbl[idx].setter(result);
if( result > 1 )
return false; // or whichever way your logic is (an enum might be better)
}
return true;
}
(And, no, I'm not going to attempt to write down the correct syntax for a member function pointer's type. I've always had to look this up and still never ot this right the first time... But I know it's doable.)
Exceptions are meant for cases that shouldn't happen during normal operation. They're hardly non-intrusive; their very nature involves unwinding the call stack, calling destructors all over the place, yanking the control to a whole other section of code, etc. That stuff can be expensive, depending on how much of it you end up doing.
Even if it were free, though, using exceptions as a normal flow control mechanism is a bad idea for one other, very big reason: exceptions aren't meant to be used that way, so people don't use them that way, so they'll be looking at your code and scratching their heads trying to figure out why you're throwing what looks to them like an error. Head-scratching usually means you're doing something more "clever" than you should be.