I am attempting to create a custom system call that inputs an (long) array and outputs some basic information about this array for a class assignment.
I am having some trouble passing the appropriate arguments into the system call.
Below is the test program I am using to debug this system call:
#include <stdio.h>
#include <unistd.h>
#include <sys/syscall.h>
#include "array_stats.h"
#define _ARRAY_STATS_ 341 // for a 64 bit system
int main () {
struct array_stats * stats;
long ary[3];
ary[0] = 1;
ary[1] = 2;
ary[2] = 3;
long s = 3;
printf("\nDiving to kernel level\n\n");
// Calling array_stats syscall
int result = syscall(_ARRAY_STATS_, &stats, ary, s);
printf("\nRising to user level w/ result = %d\n\n", result);
return 0;
}
Here is the array_stats system call, I have inserted a bunch of printk() statements for debugging purposes:
#include <linux/kernel.h>
#include <asm/errno.h>
#include <linux/uaccess.h>
#include "array_stats.h"
asmlinkage long sys_array_stats (struct array_stats *stats, long data[], long size) {
printk("1. %s\n", "System call started");
long loc_max;
long loc_min;
long loc_sum;
long local_data[size];
int i = 1;
int result = 0;
printk("2. %s\n", "Variables created");
printk("Size %lu\n", size);
printk("data[0] = %lu\n", data[0]);
printk("data[1] = %lu\n", data[1]);
printk("data[2] = %lu\n", data[2]);
if (size <= 0) return -EINVAL;
printk("3. %s\n", "Size validated");
result = copy_from_user (local_data, data, size * sizeof * data);
if (!result) return EFAULT;
loc_max = local_data[0];
loc_min = local_data[0];
loc_sum = local_data[0];
for (; i < loc_sum; i++) {
loc_sum += local_data[i];
if (local_data[i] < loc_min) loc_min = local_data[i];
if (local_data[i] > loc_max) loc_max = local_data[i];
}
stats -> min = loc_min;
stats -> max = loc_max;
stats -> sum = loc_sum;
printk("Min: %lu\n", loc_min);
printk("Max: %lu\n", loc_max);
printk("Sum: %lu\n", loc_sum);
return result;
}
The running of the test program results in the following:
root#debian-amd64:~# ./array_stats_test
Diving to kernel level
[ 92.735994] 1. System call started
[ 92.737851] 2. Variables created
[ 92.738037] Size 0
[ 92.738155] data[0] = 0
[ 92.738417] data[1] = 6955032
[ 92.738565] data[2] = 0
Rising to user level w/ result = -1
root#debian-amd64:~#
As you can see, the arguments aren't being passed in properly. What am I doing wrong?
Thanks in advance!
Related
This program reads the domain from a file to a string, truncates the string with "\n" as a key, and then executes the getostbyname() function for each domain to enter the resulting information into the file.
When I use gethostbyname, I want to create a function to enter fail if there is no response for a certain period of time. I tried to implement and process the timeout function, but the function did not work.
The logic that I thought of is calling gethostbyname() and entering fail in the file if there is no response for two seconds, then proceed to the next string and call gethostbyname().
The amount of files is about 150 million domains, so I took only a part of them and made them an example.
Please help me create the functions I want.
This is input.txt
www.naver.com
kbphonemall.com
kbplant.com
k-bplus.com
kbpointreestore.com
kbprint.com
kbprism.com
kbprivatebanking.com
kbpstore.com
kbr9rtudaf5ppy.com
kbrafting.com
kbraille.com
kbrainbank.com
kbrainbow.com
kbrainc.com
kbrainglocal.com
kbrandexpo.com
kbrandingschool.com
kbrandmall.com
kbrandmuseum.com
kbranking.com
k-bread.com
k-breadshop.com
kbreaknews.com
kbreasy.com
kbr-easy.com
kb-rent.com
kbrentacar.com
kb-rentcar.com
kbreport.com
k-brew.com
kbrewtec.com
kbrick.com
kbridge21.com
kbrno.com
k-broad.com
kbrockstar.com
kbrosbeauty.com
kbrosis.com
kbrworks.com
kbs1004.com
kbs123.com
kbs20.com
kbs220.com
kbs3.com
kbs31.com
kbs336.com
kbs358.com
kbs40.com
kbs556.com
kbs5678.com
kbs69.com
kbs7.com
kbs700.com
kbs79.com
kbs87.com
kbs9003.com
kbs911.com
kbs97.com
kbsarchive.com
kbsavers.com
kbsavings.com
kbsavingstar.com
kbsba.com
kbsbaechoo.com
kbsbook.com
kbsc1.com
kbscarf.com
kbsccoding.com
kbscert.com
kbschoolbanking.com
kbscyerrutb.com
kbsec.com
kbsec-greeting.com
kbsecuritynews.com
kbseschool.com
kbsestudy.com
kbsfn.com
kbsgmp.com
kbsgreen.com
kbsgulbee.com
kbs-hip.com
kbsholdings.com
kbshsg.com
kbsisa.com
kbsjeju.com
kbskadt.com
kbskiotmall.com
kbsklt.com
kbskorea.com
kbskorean.com
kbskovo.com
kbsktw.com
kbsktwidea.com
kbslogos.com
kbslove.com
kbs-lse.com
kbsmc-ibd.com
kbsmcob.com
kbsmedi.com
kbsmetal.com
kbsmol.com
kbs-mt.com
kbsmt-academy.com
kbsnd.com
kbsnews.com
kbsnnews.com
kbsonbocns.com
kbsonbodirect.com
kbsonsa.com
kbspetdoc.com
kbsplus.com
kbspro.com
kbsq.com
kbssky.com
kbssomgr.com
kbssports.com
kbsstudy.com
kbstar.com
kbstar2020.com
kbstar21.com
kbstar24.com
kbstarb.com
kbstarcard.com
kbstarclub.com
kbstardirect.com
kbstarebank.com
kbstarfg.com
kbstarfinance.com
kbstarflower.com
kbstarfx.com
kbstarg.com
kbstarir.com
kbstarland.com
kbstarmail.com
kbstarmall.com
kbstarmbank.com
kbstarmoney.com
kbstarpb.com
kbstarsvc.com
kbstarworld.com
kbstarzone.com
kbstbt.com
kbsteel.com
kbstock1.com
kbstock5.com
kbs-travel.com
kbstructure.com
kbstv.com
kbstve.com
kbsuf.com
kbsupercard.com
kbsupporters.com
kbsv.com
kbsvoice.com
kbtac.com
kbtchain.com
kbtechgate.com
kbtechone.com
kbtechpos.com
kbtechshop.com
kbtilbo.com
kb-truck.com
kbtups.com
kbtva.com
kbubi.com
kbuddhism.com
k-buddhism.com
k-buddy.com
kbujejucall.com
kbulgyonews.com
k-bulls.com
kbumall.com
kbund.com
kb-uniform.com
kbusinessnews.com
kbusinfo.com
kbusking.com
kbuvd.com
kbvalve.com
kbvipstock.com
kbweb.com
kbweddingfair.com
kbwel.com
kbwith.com
kbwlab.com
kbwnet.com
kb-world.com
kbworldwide.com
kb-world-wide.com
kby8992.com
kbynews.com
kc005.com
kc04.com
kc0522.com
kc1004.com
kc114.com
kc1357.com
kc1895.com
kc1904.com
kc22.com
kc25.com
kc712.com
kc9479.com
kc97bkyg3tvzgdws.com
kca2009.com
kca21.com
kca7.com
kcaa1.com
kcaa12.com
kcaa21.com
kca-academy.com
kcaawelfare.com
kcabiz.com
kca-charcoal.com
kcadcom.com
k-caddie.com
k-cae.com
kcafrp.com
kcagcf.com
kcagolf.com
kcagym.com
kcahub.com
kcairfiltertech.com
kcakca.com
kcakn.com
kcakorea.com
kcakyrgyz.com
kcallica.com
kcaltrip.com
kcangle.com
kcar.com
k-car.com
kcar2.com
kcaratpay.com
kcarauction.com
kcaraudio.com
kcarb2b.com
kcarcapital.com
kcar-capital.com
kcard.com
kcardirect.com
kcar-direct.com
k-cardirect.com
k-careeraptitude.com
kcarfriends.com
kcarlogis.com
kcarmall.com
kcarnet.com
kcarschool.com
kcarz.com
k-cata.com
kcateam.com
kcatfree.com
kca-therapy.com
kcb4u.com
kcb5.com
kcbc-acc.com
kcbcard.com
kcbec.com
kcbend.com
kcbetrade.com
kcbexchange.com
kcbiea.com
kc-biz.com
kcboltec.com
kcbs119.com
kcbtec.com
kcbtv.com
kcbunion.com
kcc000.com
kcc001.com
kcc002.com
kcc003.com
kcc007.com
kcc1004.com
kcc1122.com
kcc114.com
kcc2.com
kcc21.com
kcc258.com
kcc339.com
kcc5858.com
kcc775.com
kcc7777.com
kcc7979.com
kcc8282.com
kccaedu.com
kccardpos.com
kccarr.com
kccaster.com
kccasters.com
kccauto.com
kccce.com
kccchem.com
kccckorea.com
kcccolorndesign.com
kcccontainer.com
kccdeco.com
kccdepot.com
kccea.com
kccegis.com
kccei.com
kcceleader.com
kccenc.com
kccepost.com
kcceramice.com
kcceye.com
kccf2012.com
kccfilm.com
kccflooring.com
kccgift.com
kccglass.com
kccgroup.com
kcchain.com
kccheavyduty.com
kccholdings.com
kcchomecc.com
kcchomeccinterior.com
kcchwarang.com
kccia.com
kccichem.com
kccinsight.com
kccinterior.com
kccjewelry.com
kcckdong.com
kccks.com
kccmarine.com
kccmaul.com
kccnara.com
kccofficial.com
kccold.com
kccomang.com
kccond.com
kcconveyor.com
kc-coop.com
kc-cottrell.com
kccpaint114.com
kccpaintmall.com
kccplant.com
kccplus.com
kccpr.com
kccrefinish.com
kccrose.com
kccsa.com
kccscleaning.com
kccseoul.com
kccsilicon.com
kccsilicone.com
kccsmms.com
kccssafe.com
kccswitzen-patio.com
kcctm.com
kcctour.com
kccultural.com
kccview.com
kccvma.com
kccwelltztower.com
kccwindow.com
kccwindows.com
kccworld.com
kccycasters.com
kccyes.com
kcdc2020.com
kcdc21.com
kcdcode.com
kcdeaf.com
kcdfarm.com
kcdic.com
kcdkorea.com
kcdoll.com
kcdoor.com
k-cea.com
kcea98.com
kceasw.com
kceautodoor.com
kceccenter.com
kcecctv.com
kcecoin.com
kcecrs.com
and this is code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <time.h>
#include <sys/time.h>
#include <unistd.h>
#include <signal.h>
#define IPATH "example.txt"
#define OPATH "result/output.txt"
struct hostent *host;
int whatthe = 0;
void sig_handler(int signum){
host = NULL;
}
void dnslookup(char temp1[]){
host = gethostbyname(temp1);
}
int main(int argc, char *argv[]){
struct timeval tv;
double begin, end;
gettimeofday(&tv, NULL);
begin = (tv.tv_sec) * 1000 + (tv.tv_usec) / 1000 ;
char *ListBuffer;
int ListSize;
FILE *InputFile = fopen(IPATH, "r");
FILE *OutputFile = fopen(OPATH, "w");
fseek(InputFile, 0, SEEK_END);
ListSize = ftell(InputFile); //길이를 재고
ListSize ++; //NULL 문자가 들어갈 자리까지 해줌. 문자열의 끝을 알기 위해서
ListBuffer = malloc(ListSize); //잰 길이만큼 동적할당
memset(ListBuffer, 0, ListSize); //할당한 메모리 초기화
ListBuffer[ListSize] = '\0';
fseek(InputFile, 0, SEEK_SET);
fread(ListBuffer, ListSize, 1, InputFile); //읽어와서 동적할당한 배열에 넣기
char temp[] = {0, };
char *temp2;
int count = 0;
int h_count = 0;
char *str1 = NULL;
char *temp1 = strtok_r(ListBuffer, "\n", &str1);
while (temp1 != NULL){
dnslookup(temp1);
signal(SIGALRM,sig_handler);
alarm(2);
if (host != NULL){
fprintf(OutputFile, "%s / %s\n", temp1, inet_ntoa(*(struct in_addr *)host->h_addr_list[0]));
}
else{
fprintf(OutputFile, "%s / %s\n",temp1, "FAIL");
}
temp1 = strtok_r(NULL, "\n", &str1);
}
fclose(InputFile); //파일 포인터 닫기
fclose(OutputFile); //파일 포인터 닫기
free(ListBuffer); // 동적 메모리 해제
ListBuffer = NULL;
gettimeofday(&tv, NULL);
end = (tv.tv_sec) * 1000 + (tv.tv_usec) / 1000 ;
// 출력
printf("Execution time %f\n", (end - begin) / 1000);
}
what is problem?
If you need more explanation, I'll answer it quickly.
Thank you for reading my question. Have a nice day.
Use setjmp() & longjmp() pair with alarm().
#include <setjmp.h>
#define DNS_TIMEOUT 2 // timeout you need
static jmp_buf env;
void sig_handler (int signum) {
//host = NULL;
longjmp (env, 1); // jump to setjmp() location with value 1
}
int dnslookup (const char* domain) {
#define STATUS_TIMEOUT 128 // custom: timeout occurred
int status = 0;
signal (SIGALRM, sig_handler);
if (0 == setjmp(env)) { // to return here after timeout with return value 1
alarm (DNS_TIMEOUT); // setting timeout
host = gethostbyname (domain);
signal (SIGALRM, SIG_DFL);
alarm (0); // cancel alarm
} else { // after timeout-alarm we're here
// you may want to record TIMEOUT instead of FAIL
status = STATUS_TIMEOUT;
host = NULL;
//printf ("\nTimeout for %s", domain);
}
return status;
}
Also:
ListBuffer = malloc(ListSize); //잰 길이만큼 동적할당
memset(ListBuffer, 0, ListSize); //할당한 메모리 초기화 // not necessary
//ListBuffer[ListSize] = '\0'; // BUFFER-OVERFLOW
...
char *rmdList = NULL;
char *domain = strtok_r (ListBuffer, "\n", &rmdList);
while (domain != NULL) {
int status = dnslookup (domain);
// signal (SIGALRM, sig_handler);
// alarm (2);
if (host)
fprintf (OutputFile, "%s / %s\n", domain, inet_ntoa (* (struct in_addr *) host->h_addr_list[0]));
else if (STATUS_TIMEOUT == status)
fprintf (OutputFile, "%s / %s\n", domain, "TIMEOUT");
else
fprintf (OutputFile, "%s / %s\n", domain, "FAIL");
domain = strtok_r (NULL, "\n", &rmdList);
}
That said :
The gethostbyname*(), gethostbyaddr*(), herror(), and hstrerror()
functions are obsolete. Applications should use getaddrinfo(3),
getnameinfo(3), and gai_strerror(3) instead.
I had a problem initializing the PMU in gem5 for an arm full system with the starter_fs.py in --cpu hpi.
i followed the instructions of this post Using perf_event with the ARM PMU inside gem5 and i managed to solve my problem. I added the patch and configure the system. I am not using perf. I try to access directly the registers and read them. As i see GEM5 has only some register events implemented. Can we add the others as well as :
for example EXC_TAKEN is not implemented. Is the following the way to add them?
self.addEvent(ProbeEvent(self,0x09, cpu, "EXC_TAKEN"))
#0x09: EXC_TAKEN ???
Also, reading the pmu event registers i manage to read them and extract the events but the pmccntr cycle register always returns zero? How gem5 increments this register? What are the steps to read the cycle reggister?
a code that i use to read using perf is the following:
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <linux/perf_event.h>
#define NUM_NODES 100
#define NONE 9999
struct _NODE
{
int iDist;
int iPrev;
};
typedef struct _NODE NODE;
struct _QITEM
{
int iNode;
int iDist;
int iPrev;
struct _QITEM *qNext;
};
typedef struct _QITEM QITEM;
QITEM *qHead = NULL;
int AdjMatrix[NUM_NODES][NUM_NODES];
int g_qCount = 0;
NODE rgnNodes[NUM_NODES];
int ch;
int iPrev, iNode;
int i, iCost, iDist;
void print_path (NODE *rgnNodes, int chNode)
{
if (rgnNodes[chNode].iPrev != NONE)
{
//print_path(rgnNodes, rgnNodes[chNode].iPrev);
}
//printf (" %d", chNode);
fflush(stdout);
}
void enqueue (int iNode, int iDist, int iPrev)
{
QITEM *qNew = (QITEM *) malloc(sizeof(QITEM));
QITEM *qLast = qHead;
if (!qNew)
{
//fprintf(stderr, "Out of memory.\n");
exit(1);
}
qNew->iNode = iNode;
qNew->iDist = iDist;
qNew->iPrev = iPrev;
qNew->qNext = NULL;
if (!qLast)
{
qHead = qNew;
}
else
{
while (qLast->qNext) qLast = qLast->qNext;
qLast->qNext = qNew;
}
g_qCount++;
// ASSERT(g_qCount);
}
void dequeue (int *piNode, int *piDist, int *piPrev)
{
QITEM *qKill = qHead;
if (qHead)
{
// ASSERT(g_qCount);
*piNode = qHead->iNode;
*piDist = qHead->iDist;
*piPrev = qHead->iPrev;
qHead = qHead->qNext;
free(qKill);
g_qCount--;
}
}
int qcount (void)
{
return(g_qCount);
}
int dijkstra(int chStart, int chEnd)
{
for (ch = 0; ch < NUM_NODES; ch++)
{
rgnNodes[ch].iDist = NONE;
rgnNodes[ch].iPrev = NONE;
}
if (chStart == chEnd)
{
//printf("Shortest path is 0 in cost. Just stay where you are.\n");
}
else
{
rgnNodes[chStart].iDist = 0;
rgnNodes[chStart].iPrev = NONE;
enqueue (chStart, 0, NONE);
while (qcount() > 0)
{
dequeue (&iNode, &iDist, &iPrev);
for (i = 0; i < NUM_NODES; i++)
{
if ((iCost = AdjMatrix[iNode][i]) != NONE)
{
if ((NONE == rgnNodes[i].iDist) ||
(rgnNodes[i].iDist > (iCost + iDist)))
{
rgnNodes[i].iDist = iDist + iCost;
rgnNodes[i].iPrev = iNode;
enqueue (i, iDist + iCost, iNode);
}
}
}
}
//printf("Shortest path is %d in cost. ", rgnNodes[chEnd].iDist);
//printf("Path is: ");
//print_path(rgnNodes, chEnd);
//printf("\n");
}
}
int main(int argc, char *argv[]) {
int diff = 0;
uint64_t num_cycles_nominal=0;
uint64_t num_cycles_attack=0;
uint64_t counter_cpu_cycles = 0;
//system("./load-module");
int i,j,k;
FILE *fp;
static int perf_fd_cpu_cycles;
static struct perf_event_attr attr_cpu_cycles;
attr_cpu_cycles.size = sizeof(attr_cpu_cycles);
attr_cpu_cycles.exclude_kernel = 1;
attr_cpu_cycles.exclude_hv = 1;
attr_cpu_cycles.exclude_callchain_kernel = 1;
attr_cpu_cycles.type = PERF_TYPE_RAW;
attr_cpu_cycles.config = 0x11;
/* Open the file descriptor corresponding to this counter. The counter
should start at this moment. */
if ((perf_fd_cpu_cycles = syscall(__NR_perf_event_open, &attr_cpu_cycles, 0, -1, -1, 0)) == -1)
fprintf(stderr, "perf_event_open fail %d %d: %s\n", perf_fd_cpu_cycles, errno, strerror(errno));
if (argc<2) {
//fprintf(stderr, "Usage: dijkstra <filename>\n");
//fprintf(stderr, "Only supports matrix size is #define'd.\n");
}
/* open the adjacency matrix file */
fp = fopen (argv[1],"r");
/* make a fully connected matrix */
for (i=0;i<NUM_NODES;i++) {
for (j=0;j<NUM_NODES;j++) {
/* make it more sparce */
fscanf(fp,"%d",&k);
AdjMatrix[i][j]= k;
}
}
/* Get and close the performance counters. */
read(perf_fd_cpu_cycles, &counter_cpu_cycles, sizeof(counter_cpu_cycles));
//close(perf_fd_cpu_cycles);
printf("Number of cpu_cycles before: %d\n", counter_cpu_cycles);
num_cycles_nominal = counter_cpu_cycles;
/* Get and close the performance counters. */
read(perf_fd_cpu_cycles, &counter_cpu_cycles, sizeof(counter_cpu_cycles));
//close(perf_fd_cpu_cycles);
printf("Number of cpu_cycles after attack: %d\n", counter_cpu_cycles);
num_cycles_attack = counter_cpu_cycles - num_cycles_nominal;
/* finds 10 shortest paths between nodes */
for (i=0,j=NUM_NODES/2;i<100;i++,j++) {
j=j%NUM_NODES;
dijkstra(i,j);
}
read(perf_fd_cpu_cycles, &counter_cpu_cycles, sizeof(counter_cpu_cycles));
close(perf_fd_cpu_cycles);
printf("Number of cpu_cycles end: %d\n", counter_cpu_cycles);
num_cycles_nominal = counter_cpu_cycles - num_cycles_attack;
printf("Number of cpu_cycles nominal: %d\n", num_cycles_nominal);
printf("Number of cpu_cycles attack: %d\n", num_cycles_attack);
exit(0);
}
the problem is that i can read the branch misses with perf having 0x10 instead 0f 0x11 (cycle counters RAW EVENT in GEM5) but using 0x11 for reading the cycles i get zero. When i try to reverse engineer the increment of cycle counter i do the following comments:
when simple/atomic or simple/timing i see that updateCycleCounter is called from the base.hh, also for the 03 cpu model. When HPI and considering that hpi is a MinorCPU model i see that updateCycleCounter is called only in POWER_STATE_ON, but i didnt find in the code a POWER_STATE_ON reference updateCycleCounter(CPU_STATE_ON) which will update the cycle counter. Please help me verify this assumption.
*****The problem was that in the MinorCPU the updateCycleCounter wasnt called for the CPU_STATE_ON which updates the ActiveCycles. It was fixed by the following patch https://gem5-review.googlesource.com/c/public/gem5/+/38095 .
I have been working out an example to demonstrate multithreading using POSIX on processing operation of an image. The encoding was done with lodepng library. I wanted the code to break a color inverse process of any loaded image into 4 equal threads. Although I have checked repeatedly, I still cant find out why the 4th thread starting and ending values are getting modified inside the threadFunc2() function. Its the same code used by other 3 threads getting correct start and end values. I have used a structure to pass start, end and thread number data into function. For example, if I load a 10x10 image which results in 100 pixels (each with 4 values for R,G, B and Transparency),it requires a 400 element array to store each color value. The 4th thread should start with 300 and 399. Its correctly calculated in the main() function before passing to function, but ends up as being 5 and 6 within the threadFunc2() at start.
#include <pthread.h>
#include "lodepng.h"
#include <stdio.h>
#include <stdlib.h>
#include "lodepng.c"
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
unsigned int error;
unsigned int encError;
unsigned char* image;
unsigned int width;
unsigned int height;
int Arraysize;
const char* filename = "10x10Circle.png";
const char* newFileName = "10x10Result.png";
struct Markers{int start;int end;int no};
void *threadFunc(void *arg){ // function to load the image into an array
pthread_mutex_lock(&mutex);
error = lodepng_decode32_file(&image, &width, &height, filename);
if(error){
printf("error %u: %s\n", error, lodepng_error_text(error));
}
Arraysize = 4*height*width;
printf("arraysize:%d, %d \n",sizeof(image)/sizeof(image[0]),Arraysize);
pthread_mutex_unlock(&mutex);
return NULL; }
void *threadFunc2(void *arg){ //function to apply inverse process on loaded data
struct Markers*vars= (struct Markers*) arg;
printf("Thread %d start|start-%d,end-%d\n",vars->no,vars->start,vars->end);
for( int i = vars->start; i<(vars->end); i=i+4){
pthread_mutex_lock(&mutex);
image[0+i]= 255-image[0+i];
image[1+i]= 255-image[1+i];
image[2+i]= 255-image[2+i];
image[3+i]= 255-image[3+i];// can be ignored
printf("Thread: %d,round:%d\n",vars->no,i);// debug line
pthread_mutex_unlock(&mutex);
}
// printf("Thread: %d,after end:%d\n",vars->no,i);
printf("**************************\n");
printf("Thread end\n");
return NULL;
}
void *encodeprocessed(){
encError = lodepng_encode32_file(newFileName, image, width, height);
if(encError){
printf("error %u: %s\n", error, lodepng_error_text(encError)); }
free(image); }
Following is the main function
int main(void){
pthread_t pth,pth0, pth1, pth2, pth3;
pthread_create(&pth,NULL,threadFunc,NULL);
pthread_join(pth, NULL );
struct Markers Positions[3];
Positions[0].start = 0;
Positions[0].end = Arraysize/4 -1;
Positions[0].no = 1;
Positions[1].start =Arraysize/4;
Positions[1].end = Arraysize/2 -1;
Positions[1].no = 2;
Positions[2].start =Arraysize/2;
Positions[2].end = Arraysize*3/4 -1;
Positions[2].no = 3;
Positions[3].start =(Arraysize*3)/4;
Positions[3].end = Arraysize -1;
Positions[3].no = 4;
//debug line
printf("%d,%d,%d,%d,%d,%d,%d,%d,%d\n",Arraysize,Positions[0].start,Positions[0].end,
Positions[1].start,Positions[1].end,Positions[2].start,Positions[2].end,
Positions[3].start,Positions[3].end);
pthread_create(&pth0,NULL,threadFunc2,&Positions[0]);
pthread_create(&pth1,NULL,threadFunc2,&Positions[1]);
pthread_create(&pth2,NULL,threadFunc2,&Positions[2]);
pthread_create(&pth3,NULL,threadFunc2,&Positions[3]);
pthread_join(pth0, NULL );
pthread_join(pth1, NULL );
pthread_join(pth2, NULL );
pthread_join(pth3, NULL );
encodeprocessed();
return 0;}
The code is running without any errors. Image gets inverted only 75% and gets saved. Anyone who can give me a clue is much appreciated.
Even though we set currentMethod.bytes with local function to generate random numbers, the RAND_bytes is not invoking. After we set RAND_set_rand_method(&cuurentMethod).
Here I attached link [https://github.com/openssl/openssl/blob/master/test/sm2_internal_test.c] which I already tried.
int main()
{
unsigned char rand[16];
int ret;
RAND_METHOD *oldMethod,currentMethod,*temp;
oldMethod = RAND_get_rand_method();/*getting default method*/
currentMethod = *oldMethod;
currentMethod.bytes = local_function_rand;
if((ret = RAND_set_rand_method(¤tMethod))!= 1)
return 0;
/* Now we are printing both address of local_function_method_rand() and
temp->bytes , those address are same after getting. */
temp = RAND_get_rand_method();
/* after we are comparing with RAND_SSLeay() function , to find default or not*/
if((ret = RAND_bytes(rand,16)) != 1)
return 0;
return 1;
}
Expecting result is our local function should invoke. Also, to invoke RAND_bytes() is it required to set fips mode in Linux system?
After cleaning up and minimizing your test program and filling in the missing parts:
#include <openssl/rand.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int local_function_rand(unsigned char *buf, int num) {
printf("in local_function_rand(); requested %d bytes\n", num);
memset(buf, 4, num); // RFC 1149.5 standard random number
return 1;
}
int main(void) {
unsigned char rand[16];
RAND_METHOD currentMethod = {.bytes = local_function_rand};
RAND_set_rand_method(¤tMethod);
if (RAND_bytes(rand, sizeof rand) != 1) {
return EXIT_FAILURE;
}
return 0;
}
and running it (With OpenSSL 1.1.1):
$ gcc -Wall -Wextra rand.c -lcrypto
$ ./a.out
in local_function_rand(); requested 16 bytes
it works as expected; the user-supplied function is being called by RAND_bytes(). If you're getting different results from your code, there's probably a problem in the bits you didn't include in your question.
I have been debugging the following code for the past few hours. I realize it is probably something stupid, but can't seem to figure it out.
In the second for loop (see debug printfs) the value of bitsA changes. I can't figure out why.
EDIT: In case anyone was wondering what the code in sat_count_update is:
counter->taken = (bool)((1 << counter->cbits - 1) & counter->count) ;
File: SaturatingCounter.H
#ifndef SATURATINGCOUNTER_H
#define SATURATINGCOUNTER_H
#include <stdbool.h>
//Macro function to return taken/not taken of counter
#define sat_count_taken(COUNTER) COUNTER->taken
typedef struct sat_count{
char count;
char cbits;
bool taken;
} sat_count_t;
//Initialize and return counter
void sat_count_init(char bits, sat_count_t *counter){
counter->count = 0;
counter->cbits = bits;
counter->taken = false;
}
//Update taken member of sat_counter_t based on count
void sat_count_update(sat_count_t *counter){
//COMMENTING OUT THIS LINE MAKES IT WORK. NORMALLY THERE IS CODE TO SET THE CORRECT VALUE
counter->taken = true;
}
//Up counter, respecting saturation
void sat_count_up(sat_count_t *counter){
//If counter is saturated
if ((counter->count < ( 1 << counter->cbits) - 1)) counter->count = counter->count + 1;
sat_count_update(counter);
}
//Down counter, respecting saturation
void sat_count_down(sat_count_t *counter){
//If counter is 0
if (counter->count > 0) --counter;
sat_count_update(counter);
}
#endif
SaturatingCounterTest.H
#include "SaturatingCounter.H"
#include "SaturatingCounter.H" //Multiple include to test include guards
#include <stdbool.h>
#include <stdio.h>
void main(){
//Initialize counter
char i,NULL1, NULL2, bitsA;
sat_count_t mycounter;
//Test all bit counters
for(bitsA=1;bitsA<=5;++bitsA){
sat_count_init(bitsA,&mycounter);
printf("***************************** %d bits **************\n",bitsA);
printf("**UP**\n");
for(i=0;i<((1<<bitsA) + 1);i++) {
printf("Counter is currently %d, %sTAKEN.\n",mycounter.count,(!mycounter.taken) ? "NOT " : "");
sat_count_up(&mycounter);
}
printf("**DOWN**\n");
for(i=0; i<(((1<<bitsA) + 1));i++) {
printf("Counter is currently %d, %sTAKEN.\n",mycounter.count,(!mycounter.taken) ? "NOT " : "");
//THIS IS WHERE bitsA CHANGES!
printf("DEBUG BEFORE: BITS: %d\n",bitsA);
// printf ("%p bitsA\n %p mycounter\n",&bitsA, &mycounter);
sat_count_down(&mycounter);
printf("DEBUG AFTER: BITS: %d\n",bitsA);
// printf ("%p bitsA\n %p mycounter\n",&bitsA, &mycounter);
}
}
}
Your problem is in the line
if (counter->count > 0) --counter;
You are changing where counter is pointing - and the previous memory location is where you store bitsA :
char i,NULL1, NULL2, bitsA;
sat_count_t mycounter;
I suppose you meant to decrement something else - maybe
if(count->count > 0) --(counter->count)