Sending strings to BPF Map Space and printing them out - bpf

I have a small txt file that I would like to write to BPF here. Here is what my python code looks like for BPF but I am unable to print out anything as of now. I keep ending up with a Failed to load program: Invalid argument with a bunch of register errors. As of now my string basically says hello, world, hi
BPF_ARRAY(lookupTable, char, 512);
int helloworld2(void *ctx)
{
//print the values in the lookup table
#pragma clang loop unroll(full)
for (int i = 0; i < 512; i++) {
char *key = lookupTable.lookup(&i);
if (key) {
bpf_trace_printk("%s\n", key);
}
}
return 0;
}
Here is the Python code:
b = BPF(src_file="hello.c")
lookupTable = b["lookupTable"]
#add hello.csv to the lookupTable array
f = open("hello.csv","r")
file_contents = f.read()
#append file contents to the lookupTable array
b_string1 = file_contents.encode('utf-8')
b_string1 = ctypes.create_string_buffer(b_string1)
lookupTable[0] = b_string1
f.close()
b.attach_kprobe(event=b.get_syscall_fnname("clone"), fn_name="helloworld2")
b.trace_print()
I have the error linked in this pastebin since it's so long:
BPF Error
One notable error is the mention of infinite loop detected which is something I would need to check out.

The issue is that i is passed by pointer in bpf_map_lookup_elem, so the compiler can't actually unroll the loop (from its point of view, i may not linearly increase).
Using an intermediate variable is enough to fix this:
BPF_ARRAY(lookupTable, char, 512);
#define MAX_LENGTH 1
int helloworld2(void *ctx)
{
//print the values in the lookup table
#pragma clang loop unroll(full)
for (int i = 0; i < 1; i++) {
int k = i;
char *key = lookupTable.lookup(&k);
if (key) {
bpf_trace_printk("%s\n", key);
}
}
return 0;
}

Related

Unable to Get Bitwise XOR to work in GameMaker 2

I'm trying to implement Zobrist hashing for a chess game and thought I was doing things correctly. However, when I try to apply XOR to a Hash value, it simply changes between 0 (the starting value for the hash) and -2147483648, in spite of conducting a bitwise XOR against a random number between 0 and 18446744073709551616.
Here's some code. I thought it was relatively simple with a struct for each entry in the Grid, a constructor function to make an entry, a function to create the Hash Table, and finally one for the Hash itself.
//Hash Table struct. This can be expanded for each new piece type
HashTableEntry = {
QueenHash:-1,
BishopHash:-1,
KnightHash:-1,
RookHash:-1,
PawnHash:-1,
KingHash:-1
};
//A function for creating a Hash Table Entry
function toHashTableEntryStruct() constructor {
var HashUpperBound = 18446744073709551616;
QueenHash = random(HashUpperBound);
BishopHash = random(HashUpperBound);
KnightHash = random(HashUpperBound);
RookHash = random(HashUpperBound);
PawnHash = random(HashUpperBound);
KingHash = random(HashUpperBound);
}
//A function to create a ds_grid Hash Table of the size passed to it, which it then returns
function CreateHashTable(_width, _height){
//Copy the local variables
var width = _width;
var height = _height;
//Create the grid for the Hash Table
var NewHashTable = ds_grid_create(width, height);
//Copy the original seed and set the game's seed to create the same table each time
var OriginalSeed = random_get_seed;
random_set_seed(280804);
//Loop through the Grid and fill each value with a HashTableEntry struct
for(var i = 0; i < width; i++;){
for(var j = 0; j < height; j++;){
var NewHash = new toHashTableEntryStruct();
ds_grid_set(NewHashTable, i, j, NewHash);
}
}
//Reset the seed
random_set_seed(OriginalSeed);
//Return the shiny new Hash Table
return NewHashTable;
}
//A function for creating the original Hash of a board. This should only be called on
initialising a Board as it sets the Original Hash
function CreateBoardHash(_board){
var Board = _board;
var width = ds_grid_width(Board);
var height = ds_grid_height(Board);
HashTable = CreateHashTable(width, height);
var FinalHash = 0;
for(var i = 0; i < width; i++;){
for(var j = 0; j < height; j++;){
var PieceToCheck = ds_grid_get(Board, i, j);
if(PieceToCheck == Pieces.BLANK){ continue; }
var HashEntry = ds_grid_get(HashTable, i, j);
var XorValue = MatchPieceToHashTableEntry(PieceToCheck, HashEntry);
FinalHash ^= XorValue;
}
}
if(FinalHash == 0){
//Error here
return;
}
//Set the instance variable for this original Hash
OriginalHash = FinalHash;
//Add it to the Current Hash stack
CurrentHash = FinalHash;
//Return said hash for the calling function
return FinalHash;
}
The problem comes in the FinalHash ^= XorValue; line, where XorValue each time is a random number, but FinalHash only ever comes out as 0 or -2147483648.
Can someone help with why this is the case and what I may be doing wrong with my XOR function?
Thanks to Reddit, I have fixed this. GameMaker must be doing something weird with the ^= operator, as the solution was as follows:
FinalHash = FinalHash ^ XorValue;

array - efficiency & general approach towards the question

Edit
**After quite a bit of playing around with my code I have written few versions, one of them is what I sought for.
I'd do the following:
Create a helper Set with all the numbers from 1 to 100 - O(n) in time and space
Create an (initially) empty Set to record the indexes with 0s - O(1)
Go over the array - O(n):
If the value is 0, add the index to the index set
If the value isn't 0, remove it from the helper Set
Go over the helper set, and assign the remaining values to the indexes saved to the index set - O(m), where m<=n
All in all - an O(n) solution in time and space.
In java:
int[] numbers = /* the array with missing numbers */
Set<Integer> allNumbers = IntStream.rangeClosed(1, 100).boxed().Collect(Collectors.toSet());
Set<Ineteger> missingIndexes = new HashSet<>();
for (int i = 0; i < numbers.length; ++i) {
if (numbers[i] == 0) {
missingIndexes.add(i);
} else {
allNumbers.remove(i);
}
}
Iterator<Integer> numberIter = allNumbers.iterator();
Iterator<Integer> indexIter = missingIndexes.iterator();
while (numberIter.hasNext() && indexIter.hasNext()) {
numbers[indexIter.next()] = numberIter.next();
}
If you can sacrifice a little more space to optimize for time.
Basically just create another missing array and fill it with what's missing by traversing your helper array.
Modified your original solution.
int input [] = {5,6,0,3,0,2,1};
int output [] = new int[input.length];
boolean [] helper = new boolean[input.length];
for(int i = 0; i <input.length; i++)
{
if(input[i] != 0)
helper[i] = true;
}
int missing [] = new int[input.length];
int missingCount = 0;
for(int j = 0; j < helper.length; j++)
{
if(!helper[j]){
missing[missingCount++] = j;
}
}
missingCount = 0;
for(int j = 0; j < input.length; j++){
if(input[j]==0){
input[j]=missing[missingCount++];
}
}
Below code can find the missing element and add them back in O(n) complexity:
notFound - Will store index or location of input array having number
with zero
numberDetails - Contains details of numbers whether its present in
input array or not(true or false)
Example: input[3] = false means 4 (3+1) is not present in input array
, input[4] = true means 5 (4+1) is present in input array
int input[] = { 5, 6, 0, 3, 0, 2, 1 };
int notFound[] = new int[input.length];
boolean[] numberDetails = new boolean[input.length];
int notFoundIndex=0;
for(int i=0;i<input.length;i++) {
if(input[i]==0) {
notFound[notFoundIndex++]=i;
}
else {
numberDetails[input[i]-1]=true;
}
}
notFoundIndex=0;
for(int j=0;j<numberDetails.length;j++) {
if(!numberDetails[j]) {
input[notFound[notFoundIndex++]] = j+1;
}
}
System.out.println(Arrays.toString(input));

error: lvalue required

// getline : empty string array and max length as input
// stores input stream to array and return its length
#include<stdio.h>
#define LENGTH 100
int getline1(char* , int );
int main(){
char *s;
int i;
s=(char*)malloc(LENGTH*sizeof(char));
i=getline1(s,LENGTH);
printf("%s %d",s,i);
return 0;
}
int getline1(char *s, int lim){
int c ,i;
i = 0;
printf("%u",s);
while(--lim >= 0 && (c=getchar()) != EOF && c = '\n'){
*(s+i)=c; //error : lvalue required
i++;
}
if(c=='\n'){
*(s+i)=c;
i++;
}
*(s+i)='\0';
return i;
}
I get the error mentioned in the mentioned line can any body tell whats wrong. code works fine if i use arrays.getline : empty string array and max length as input
stores input stream to array and return its length
It cannot assign the value to the *(s+i) expression. Understandably so since you dereference it, leaving the value at that position (which is a constant).
Try using s[i] instead.

Postgres COPY command - fields with commas, quoted with double quotes

I've searched and found a few posts relating to postgres csv imports, but nothing that solves my current problem.
I use the postgres copy command all the time to bring data from hetergeneous data sources into our system. Currently struggling with a 100-million row .csv file, comma-quote delimited. Issue is with rows like so:
009098,0981098094,"something","something else",""this one, well, is a problem"", "another thing"
Fields enclosed in double-quotes with embedded commas. The fields are not correctly parsed and I get the error:
"ERROR: extra data after last expected column"
Usually when this arises I deal with the offending rows ad hoc, but this file is so huge I'm hoping for some more general way to defend against it. Asking for a revised data format is not a possibility.
copy mytable from '/path/to/file.csv' csv header quote '"'
That's malformed CSV. You double a double quote to embed a double quote inside a quote field; for example:
"where","is ""pancakes""","house?"
has three values:
where
is "pancakes"
house?
The row you're having trouble with has stray doubled double quotes:
009098,0981098094,"something","something else",""this one, well, is a problem"", "another thing"
^^ ^^
I don't think there is anything that COPY can do about this as the correct version is ambiguous: should it be "this one, well, is a problem" or should it be """this one, well, is a problem"""?
I think you'll have to fix it by hand. A quick sed one-liner should be able to do the job if you can uniquely identify the broken row.
For reference purposes, the closest thing I've seen to a CSV standard is RFC 4180 and section two has this to say:
5. Each field may or may not be enclosed in double quotes (however
some programs, such as Microsoft Excel, do not use double quotes
at all). If fields are not enclosed with double quotes, then
double quotes may not appear inside the fields. For example:
"aaa","bbb","ccc" CRLF
zzz,yyy,xxx
[...]
7. If double-quotes are used to enclose fields, then a double-quote
appearing inside a field must be escaped by preceding it with
another double quote. For example:
"aaa","b""bb","ccc"
Here is code based on the CSV code from The Practice of Programming by Kernighan and Plauger that has been adapted to deal with your weird malformed CSV data. (It wasn't all that hard to do; I already had the main code working and packaged, so I just had to add the CSV output functions and to modify the advquoted() function to handle the weird format in this question.
csv2.h
/*
#(#)File: $RCSfile: csv2.h,v $
#(#)Version: $Revision: 2.1 $
#(#)Last changed: $Date: 2012/11/01 22:23:07 $
#(#)Purpose: Scanner for Comma Separated Variable (CSV) Data
#(#)Author: J Leffler
#(#)Origin: Kernighan & Pike, 'The Practice of Programming'
*/
/*TABSTOP=4*/
#ifndef CSV2_H
#define CSV2_H
#ifdef __cplusplus
extern "C" {
#endif
#ifdef MAIN_PROGRAM
#ifndef lint
/* Prevent over-aggressive optimizers from eliminating ID string */
const char jlss_id_csv2_h[] = "#(#)$Id: csv2.h,v 2.1 2012/11/01 22:23:07 jleffler Exp $";
#endif /* lint */
#endif /* MAIN_PROGRAM */
#include <stdio.h>
extern char *csvgetline(FILE *ifp); /* Read next input line */
extern char *csvgetfield(size_t n); /* Return field n */
extern size_t csvnfield(void); /* Return number of fields */
extern void csvreset(void); /* Release space used by CSV */
extern int csvputfield(FILE *ofp, const char *field);
extern int csvputline(FILE *ofp, char **fields, int nfields);
extern void csvseteol(const char *eol);
#ifdef __cplusplus
}
#endif
#endif /* CSV2_H */
csv2.c
/*
#(#)File: $RCSfile: csv2.c,v $
#(#)Version: $Revision: 2.1 $
#(#)Last changed: $Date: 2012/11/01 22:23:07 $
#(#)Purpose: Scanner for Comma Separated Variable (CSV) Data
#(#)Modification: Deal with specific malformed CSV
#(#)Author: J Leffler
#(#)Origin: Kernighan & Pike, 'The Practice of Programming'
*/
/*TABSTOP=4*/
#ifndef lint
/* Prevent over-aggressive optimizers from eliminating ID string */
const char jlss_id_csv2_c[] = "#(#)$Id: csv2.c,v 2.1 2012/11/01 22:23:07 jleffler Exp $";
#endif /* lint */
/*
** See RFC 4180 (http://www.ietf.org/rfc/rfc4180.txt).
**
** Specific malformed CSV - see SO 13183644 (http://stackoverflow.com/questions/13183644).
** Data contains malformed CSV fields like: OK,""this is a problem"",OK
** Two (but not three) field quotes at the start extract as "this is a problem" (with the quotes).
*/
#include "csv2.h"
#include <stdlib.h>
#include <string.h>
enum { NOMEM = -2 };
static char *line = 0; /* Input line */
static char *sline = 0; /* Split line */
static size_t maxline = 0; /* Size of line[] and sline[] */
static char **field = 0; /* Field pointers */
static size_t maxfield = 0; /* Size of field[] */
static size_t nfield = 0; /* Number of fields */
static char fieldsep[]= ","; /* Field separator characters */
static char fieldquote = '"'; /* Quote character */
static char eolstr[8] = "\n";
void csvreset(void)
{
free(line);
free(sline);
free(field);
line = 0;
sline = 0;
field = 0;
maxline = maxfield = nfield = 0;
}
static int endofline(FILE *ifp, int c)
{
int eol = (c == '\r' || c == '\n');
if (c == '\r')
{
c = getc(ifp);
if (c != '\n' && c != EOF)
ungetc(c, ifp);
}
return(eol);
}
/* Modified to deal with specific malformed CSV */
static char *advquoted(char *p)
{
size_t i;
size_t j;
if (p[0] == fieldquote && (p[1] != *fieldsep && p[1] != fieldquote))
{
/* Malformed CSV: ""some stuff"" --> "some stuff" */
/* Find "\"\"," or "\"\"\0" to mark end of field */
/* If we don't find it, drop through to 'regular' case */
char *eof = strstr(&p[2], "\"\"");
if (eof != 0 && (eof[2] == *fieldsep || eof[2] == '\0'))
{
p[eof + 1 - p] = '\0';
return(eof + 2);
}
}
for (i = j = 0; p[j] != '\0'; i++, j++)
{
if (p[j] == fieldquote && p[++j] != fieldquote)
{
size_t k = strcspn(p+j, fieldsep);
memmove(p+i, p+j, k); // 1 -> i fixing transcription error
i += k;
j += k;
break;
}
p[i] = p[j];
}
p[i] = '\0';
return(p + j);
}
static int split(void)
{
char *p;
char **newf;
char *sepp;
int sepc;
nfield = 0;
if (line[0] == '\0')
return(0);
strcpy(sline, line);
p = sline;
do
{
if (nfield >= maxfield)
{
maxfield *= 2;
newf = (char **)realloc(field, maxfield * sizeof(field[0]));
if (newf == 0)
return NOMEM;
field = newf;
}
if (*p == fieldquote)
sepp = advquoted(++p);
else
sepp = p + strcspn(p, fieldsep);
sepc = sepp[0];
sepp[0] = '\0';
field[nfield++] = p;
p = sepp + 1;
} while (sepc == ',');
return(nfield);
}
char *csvgetline(FILE *ifp)
{
size_t i;
int c;
if (line == NULL)
{
/* Allocate on first call */
maxline = maxfield = 1;
line = (char *)malloc(maxline); /*=C++=*/
sline = (char *)malloc(maxline); /*=C++-*/
field = (char **)malloc(maxfield*sizeof(field[0])); /*=C++=*/
if (line == NULL || sline == NULL || field == NULL)
{
csvreset();
return(NULL); /* out of memory */
}
}
for (i = 0; (c = getc(ifp)) != EOF && !endofline(ifp, c); i++)
{
if (i >= maxline - 1)
{
char *newl;
char *news;
maxline *= 2;
newl = (char *)realloc(line, maxline); /*=C++=*/
news = (char *)realloc(sline, maxline); /*=C++-*/
if (newl == NULL || news == NULL)
{
csvreset();
return(NULL); /* out of memory */
}
line = newl;
sline = news;
}
line[i] = c;
}
line[i] = '\0';
if (split() == NOMEM)
{
csvreset();
return(NULL);
}
return((c == EOF && i == 0) ? NULL : line);
}
char *csvgetfield(size_t n)
{
if (n >= nfield)
return(0);
return(field[n]);
}
size_t csvnfield(void)
{
return(nfield);
}
int csvputfield(FILE *ofp, const char *ofield)
{
const char escapes[] = "\",\r\n";
if (strpbrk(ofield, escapes) != 0)
{
size_t len = strlen(ofield) + 2;
const char *pos = ofield;
while ((pos = strchr(pos, '"')) != 0)
{
len++;
pos++;
}
char *space = malloc(len+1);
if (space == 0)
return EOF;
char *cpy = space;
pos = ofield;
*cpy++ = '"';
char c;
while ((c = *pos++) != '\0')
{
if (c == '"')
*cpy++ = c;
*cpy++ = c;
}
*cpy++ = '"';
*cpy = '\0';
int rc = fputs(space, ofp);
free(space);
return rc;
}
else
return fputs(ofield, ofp);
}
int csvputline(FILE *ofp, char **fields, int nfields)
{
for (int i = 0; i < nfields; i++)
{
if (i > 0)
putc(',', ofp);
if (csvputfield(ofp, fields[i]) == EOF)
return EOF;
}
return(fputs(eolstr, ofp));
}
void csvseteol(const char *eol)
{
size_t nbytes = strlen(eol);
if (nbytes >= sizeof(eolstr))
nbytes = sizeof(eolstr) - 1;
memmove(eolstr, eol, nbytes);
eolstr[nbytes] = '\0';
}
#ifdef TEST
int main(void)
{
char *in_line;
while ((in_line = csvgetline(stdin)) != 0)
{
size_t n = csvnfield();
char *fields[n]; /* C99 VLA */
printf("line = '%s'\n", in_line);
for (size_t i = 0; i < n; i++)
{
printf("field[%zu] = '%s'\n", i, csvgetfield(i));
printf("field[%zu] = [", i);
csvputfield(stdout, csvgetfield(i));
fputs("]\n", stdout);
fields[i] = csvgetfield(i);
}
printf("fields[0..%zu] = ", n-1);
csvputline(stdout, fields, n);
}
return(0);
}
#endif /* TEST */
Compile the code with -DTEST to create a program with the example main() function. You need a C99 compiler; the code in main() uses a VLA (variable length array). You could avoid that with dynamic memory allocation or with pessimistic (overkill) memory allocation (an array of a few thousand pointers isn't going to kill most systems these days, but few CSV files will have a few thousand fields per line).
Example Data
Based closely on the data in the question.
009098,0981098094,"something","something else",""this one, well, is a problem"", "another thing"
123458,1234561007,"anything","nothing else",""this one, well, is a problem"","dohicky
503458,1234598094,"nothing","everything else","""this one, well, it isn't a problem""","abelone"
610078,1236100794,"everything","anything else","this ""isn't a problem"", he said.","Orcas Rule"
Example Output
line = '009098,0981098094,"something","something else",""this one, well, is a problem"", "another thing"'
field[0] = '009098'
field[0] = [009098]
field[1] = '0981098094'
field[1] = [0981098094]
field[2] = 'something'
field[2] = [something]
field[3] = 'something else'
field[3] = [something else]
field[4] = '"this one, well, is a problem"'
field[4] = ["""this one, well, is a problem"""]
field[5] = ' "another thing"'
field[5] = [" ""another thing"""]
fields[0..5] = 009098,0981098094,something,something else,"""this one, well, is a problem"""," ""another thing"""
line = '123458,1234561007,"anything","nothing else",""this one, well, is a problem"","dohicky'
field[0] = '123458'
field[0] = [123458]
field[1] = '1234561007'
field[1] = [1234561007]
field[2] = 'anything'
field[2] = [anything]
field[3] = 'nothing else'
field[3] = [nothing else]
field[4] = '"this one, well, is a problem"'
field[4] = ["""this one, well, is a problem"""]
field[5] = 'dohicky'
field[5] = [dohicky]
fields[0..5] = 123458,1234561007,anything,nothing else,"""this one, well, is a problem""",dohicky
line = '503458,1234598094,"nothing","everything else","""this one, well, it isn't a problem""","abelone"'
field[0] = '503458'
field[0] = [503458]
field[1] = '1234598094'
field[1] = [1234598094]
field[2] = 'nothing'
field[2] = [nothing]
field[3] = 'everything else'
field[3] = [everything else]
field[4] = '"this one, well, it isn't a problem"'
field[4] = ["""this one, well, it isn't a problem"""]
field[5] = 'abelone'
field[5] = [abelone]
fields[0..5] = 503458,1234598094,nothing,everything else,"""this one, well, it isn't a problem""",abelone
line = '610078,1236100794,"everything","anything else","this ""isn't a problem"", he said.","Orcas Rule"'
field[0] = '610078'
field[0] = [610078]
field[1] = '1236100794'
field[1] = [1236100794]
field[2] = 'everything'
field[2] = [everything]
field[3] = 'anything else'
field[3] = [anything else]
field[4] = 'this "isn't a problem", he said.'
field[4] = ["this ""isn't a problem"", he said."]
field[5] = 'Orcas Rule'
field[5] = [Orcas Rule]
fields[0..5] = 610078,1236100794,everything,anything else,"this ""isn't a problem"", he said.",Orcas Rule
The fields are printed twice, once to test the field extraction, once to test the field printing. You'd simplify the output by removing the printing except for csvputline() to convert your file from malformed CSV to properly formed CSV.

Unit test in xcode : inconsistent build result

Test Case '-[TestParse testParsing]' started.
/Developer/Tools/RunPlatformUnitTests.include: line 415: 3256 Segmentation fault "${THIN_TEST_RIG}" "${OTHER_TEST_FLAGS}" "${TEST_BUNDLE_PATH}"
/Developer/Tools/RunPlatformUnitTests.include:451: error: Test rig '/Developer/Platforms /iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator4.2.sdk/Developer/usr/bin/otest'
exited abnormally with code 139 (it may have crashed).
I got this seg fault message while I built test case randomly (sometime it built successfully, sometimes it throws seg fault). I'm not sure how I could fix this error.
Only thing I test here is I wrote one class name Parse with class level method. And in test case I just call it like
var = [Parse methodName:filepath];
method is like this
NSMutableDictionary *tempBox = [[NSMutableDictionary alloc] init];
FILE *fd = fopen([filePath UTF8String], "r");
if(!fd){
NSLog(#"fail to open file\n");
}
char buf[4096], *ptr;
char name[512], description[4096];
int isNewInfo = 2, description_continue = 0;
// for (line = 0; line < [args objectAtIndex:1]; line++) {
// fgets(buf, 4096, fd);
// }
while(fgets(buf, sizeof(buf), fd) != NULL){
if(strcmp(buf, "\n") == 0){
isNewInfo -= 1;
if(isNewInfo == 0){
isNewInfo = 2;
description_continue = 0;
description[strlen(description)-1] = '\0';
[self saveDrinkandResetBuf:name
detail:description box:tempBox];
if(name[0] != 0 || description[0] != 0){
NSLog(#"fail to reset...");
}
}
}
if(description_continue){
strcat(description, buf);
continue;
}
if((ptr = strstr(buf, "Drink Name: "))){
memcpy(name, buf+12, strlen(buf));
name[strlen(name)] = '\0';
continue;
}
if((ptr = strstr(buf, "Description: "))){
memcpy(description, buf+13, strlen(buf));
description_continue = 1;
continue;
}
}
fclose(fd);
NSLog(#"finish parsing section\n");
//[tempBox release];
return tempBox;
Not sure what is going on here..
I suppose, the problem is in array management.
In C if the array is declared in a function (and is not declared as a global or static one), then value of its elements is undefined. So your char description[4096] is filled with any values. And nobody said that '\0' will be there.
And the result of strlen(...) for non-null-terminated char string is not defined. It may result in a memory access violation, as it will keep counting until it reaches the first memory byte whose value is 0.
Moreover, when you call description[strlen(description)-1], strlen can return 0 (imagine that the first value, stored there initially was '\0' and your file was started with two empty lines [to reach this line of code]) - so array index will be -1...