I'm completely new to eBPF, I tried to find an answer to this but can't so I was hoping to get some help.
Take Liz's ebpf.py example
It looks like this:
BPF_HASH(clones);
int hello_world(void *ctx) {
u64 uid;
u64 counter = 0;
u64 *p;
uid = bpf_get_current_uid_gid() & 0xFFFFFFFF;
p = clones.lookup(&uid);
if (p != 0) {
counter = *p;
}
counter++;
clones.update(&uid, &counter);
return 0;
}
This then makes me wonder, for the map named clones she calls the update method. She enters a pointer to a stack-allocated variable (counter), does this not cause undefined behaviour when the stack frame is deallocated.
A possible option is that the value within the pointer is copied instead of stored as a pointer.
But then, according to this reference guide BPF_HASH can specify the leaf_type (value of the map). Meaning you can set it to a struct, which can't necessarily be copied.
I feel like I'm missing something so I'm thankful for any explanation for the matter.
A possible option is that the value within the pointer is copied instead of stored as a pointer.
That's correct. The value pointed to by the pointer is copied in the memory buffer allocated for the map's value.
Meaning you can set it to a struct, which can't necessarily be copied.
Why wouldn't that be possible? Note the kernel doesn't really care that it's a struct. It sees a pointer to a memory buffer with a size (the map's value size); it simply copies whatever is in that buffer to the memory buffer allocated for the map value.
Related
I'm guessing this question is going to apply to many similar languages other than MQL4 such as c++ (which I also forget how to use) which require you manually specify when you are passing by reference.
Method reference:
int[] previous = GetPrevious(i, ZigZagBuffer);
Method definition:
int GetPrevious[](int current, const double& buffer[])
{
int count = 0;
int result[];
// calculate count
ArrayResize(result,count);
// fill array
return result;
}
The resulting compile error is:
"Invalid Array Access"
From what I understand, this is because array's can only be passed by reference, but you have to explicitly state that you are passing it by reference. But the more I look up the syntax for passing by reference, the more I find articles about passing parameter by reference. (which I already know how to do as you can see in the code example.)
What is the syntax to assign the output of a method to a variable?
In case it matters, I only need to read the array multiple times; I'm not needing to alter or re-assign it after it is declared.
You cannot return array. You have to create it and pass into the function, fill inside the function and that's it.
OnTick(){
double array[]; //declaration of the array
fillArray(array,10); //passing array by ref, updating it there
Print(array[0]=0 && array[9]=9);//returns true
}
void fillArray(double &array[],int size){
ArrayResize(array,size);
for(int i=0;i<size;i++){array[i]=i;}
}
I am looking for examples of Chapel passing by reference. This example works but it seems like bad form since I am "returning" the input. Does this waste memory? Is there an explicit way to operate on a class?
class PowerPuffGirl {
var secretIngredients: [1..0] string;
}
var bubbles = new PowerPuffGirl();
bubbles.secretIngredients.push_back("sugar");
bubbles.secretIngredients.push_back("spice");
bubbles.secretIngredients.push_back("everything nice");
writeln(bubbles.secretIngredients);
proc kickAss(b: PowerPuffGirl) {
b.secretIngredients.push_back("Chemical X");
return b;
}
bubbles = kickAss(bubbles);
writeln(bubbles.secretIngredients);
And it produces the output
sugar spice everything nice
sugar spice everything nice Chemical X
What is the most efficient way to use a function to modify Bubbles?
Whether Chapel passes an argument by reference or not can be controlled by the argument intent. For example, integers normally pass by value but we can pass one by reference:
proc increment(ref x:int) { // 'ref' here is an argument intent
x += 1;
}
var x:int = 5;
increment(x);
writeln(x); // outputs 6
The way that a type passes when you don't specify an argument is known as the default intent. Chapel passes records, domains, and arrays by reference by default; but of these only arrays are modifiable inside the function. ( Records and domains pass by const ref - meaning they are passed by reference but that the function they are passed to cannot modify them. Arrays pass by ref or const ref depending upon what the function does with them - see array default intent ).
Now, to your question specifically, class instances pass by "value" by default, but Chapel considers the "value" of a class instance to be a pointer. That means that instead of allowing a field (say) to be mutated, passing a class instance by ref just means that it could be replaced with a different class instance. There isn't currently a way to say that a class instance's fields should not be modifiable in the function (other than making them to be explicitly immutable data types).
Given all of that, I don't see any inefficiencies with the code sample you provided in the question. In particular, here:
proc kickAss(b: PowerPuffGirl) {
b.secretIngredients.push_back("Chemical X");
return b;
}
the argument accepting b will receive a copy of the pointer to the instance and the return b will return a copy of that pointer. The contents of the instance (in particular the secretIngredients array) will remain stored where it was and won't be copied in the process.
One more thing:
This example works but it seems like bad form since I am "returning" the input.
As I said, this isn't really a problem for class instances or integers. What about an array?
proc identity(A) {
return A;
}
var A:[1..100] int;
writeln(identity(A));
In this example, the return A in identity() actually does cause a copy of the array to be made. That copy wasn't created when passing the array in to identity(), since the array was passed by with a const ref intent. But, since the function returns something "by value" that was a reference, it's necessary to copy it as part of returning. See also arrays return by value by default in the language evolution document.
In any case, if one wants to return an array by reference, it's possible to do so with the ref or const ref return intent, e.g.:
proc refIdentity(ref arg) ref {
return arg;
}
var B:[1..10] int;
writeln(refIdentity(B));
Now there is no copy of the array and everything is just referring to the same B.
Note though that it's currently possible to write programs that return a reference to a variable that no longer exists. The compiler includes some checking in that area but it's not complete. Hopefully improvements in that area are coming soon.
In a custom converter, I am checking whether a sequence item is some type. So far I've had this code (simplified)
namespace bp=boost::python;
/* ... */
static void* convertible(PyObject* seq_ptr){
if(!PySequence_Check(seq_ptr)) return 0;
for(int i=0; i<PySequence_Size(seq_ptr); i++)
if(!bp::extract<double>(PySequence_GetItem(seq_ptr,i)).check()) return 0;
/* ... */
}
/* ... */
but this is leaking memory, since PySequence_GetItem is returning a new reference. So either I can do something like this in the loop:
PyObject* it=PySequence_GetItem(seq_ptr,i);
bool ok(bp::extract<double>(it).check();
Py_DECREF(it); // will delete the object which had been newly created
if(!ok) return 0;
but that is quite clumsy; I could make a stand-alone function doing that, but that is where I recalled bp::handle implementing the ref-counting machinery; so something like this might do:
if(!bp::extract<double>(bp::handle<>(PySequence_GetItem(seq_ptr,i))).check()) return 0;
but this page mentions using handles as temporaries is discouraged. Why? Can the object be destroyed before .check() is actually called? Is there some other elegant way to write this?
The object will not be destroyed before the .check() is called and is safe in the posted context.
The recommendation to not use temporaries is due to the unspecified order of evaluation of the arguments and exception safety. If there is only one order in which arguments can be evaluated, such as in your example, then it is safe. For instance, consider function bad() which always throws an exception:
f(boost::python::handle<>(PySequence_GetItem(...)), bad());
If bad() gets evaluated between PySequence_GetItem(...) and boost::python::handle<>(...), then the new reference will be leaked as the stack will begin to unwind before the construction of boost::python::handle<>. On the other hand, when a non-temporary is used, there is no chance for something to throw between PySequence_GetItem() and boost::python::handle<>(), so the following is safe in the presence of exceptions:
boost::python::handle<> item_handle(PySequence_GetItem(...));
f(item_handle, bad());
Consider reading Herb Sutter's GotW #56: Exception-Safe Function Calls for more details.
I am using a c lib in my iPhone application. The c lib is written by someone I do not have access to.
However I am getting the error that object 0xa6000d is being freed but not allocated. The debug variable screenshot is here.
struct GtsMsg is defined as,
struct msg {
int offset;
int dataLength;
u8* data;
cBool expandable;
cBool owned;
u8* mid2key;
};
#define GtsMsg struct msg
void freeMessageData(GtsMsg* msg) {
if (msg == NULL) return;
if (msg->owned) {
if (msg->data != NULL) {
free(msg->data);
}
}
free(msg->mid2key);
memset(msg, 0, sizeof(GtsMsg));
}
The breakpoint for malloc_error_break is the line free(msg->data).
I have added the checking if (msg->data != NULL), but it did not work. What are the ways to check if the memory for msg->data or for msg is allocated or not?
Do you think there is something fishy, at *data = (u8)'\0'?
thanks in advance!
Thanks to all to your suggestions.
Thanks hmjd for your tips.
I found the struct is used in a cpp class which destructor calls the freeMessageData. But I could not find that the struct is initialized. So, if I initialize the struct to NULL in the declaration, this avoid the free memory problem and do not crash.
Its something suggested by simonc. If he writes that as an answer not, comment, I could accept that.
From comments of hmjd,
The check for NULL is useless as free() will be a no-op if the pointer
passed to it is NULL. Just because a pointer is not NULL does not mean
it points a valid memory location (the memory may have already been
freed or the pointer was never initialized to NULL). It is the
responsibility of the programmer to ensure that the pointer is valid
before attempting to free it.
Hello
I am trying to make this function to return an array! What is going wrong here?
-(char[10])print01:(int)int11{ //error: declared as method returning an array
char arrayT[10];
for(int i=0;i<8;i++)
{
if ((int1-n1)>=0){
arrayT[i]='1';
int1-=n1;
}
else
arrayT[i]= '0';
n1=n1/2;
}
return arrayT[]; // incompatible types in return
}
and I want to call it like that:
char array1[10] = [self print01:(int)int1]; //error: invalid initializer
any suggestions please?
You can't return an array in C or in Objective-C. The best you can hope for is to return a pointer to an array, but if you're going to do that, make sure you don't return a pointer to an array on the stack (like yours is).
The best approach is using an NSArray (of objects of course, I'm assuming the above code is simplified sample, but you can always use an NSNumber). Alternatively, you could return a pointer to an array, which is common in C as C (and objective c by extension) cannot return an array. Unfortunately, this would require allocating memory for the array and using manual memory management, (malloc/free) which depending on the lifecycle of the array, can be anywhere from a nuisance to awful. My recommendation is taking a char *dest parameter, and inserting chars into the array as dest[i]