I was trying to emulate what Cheat Engine does on mac os in getting the memory address from values and modifying it. I have done this so far:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <libproc.h>
#include <mach/mach_init.h>
// Get array of all process ids
uint32_t* get_pids(uint16_t* size) {
uint32_t number_of_pids = proc_listpids(1, 0, NULL, 0);
uint32_t* buffer = malloc(sizeof(uint32_t) * number_of_pids);
uint8_t return_code = proc_listpids(1, 0, buffer, sizeof(buffer) * number_of_pids);
uint16_t sum = 0;
for(int i = 0; i < number_of_pids; i++) {
if(buffer[i] != 0) {
sum++;
}
}
uint32_t* final = malloc(sizeof(uint32_t) * sum);
for(int i = 0, t = 0; i < number_of_pids; i++) {
if(buffer[i]) {
final[t++] = buffer[i];
}
}
*size = sum;
return final;
}
int main() {
uint16_t size;
uint32_t* pids = get_pids(&size);
uint16_t maxpathlength = 1024;
uint16_t path_size = maxpathlength * 4;
char path_buffer[path_size];
uint32_t pid = 0;
for(int i = 0; i < size; i++) {
memset(path_buffer, '\0', sizeof(path_buffer));
uint8_t return_code = proc_pidpath(pids[i], path_buffer, path_size);
if(strstr(path_buffer, "Geometry Dash")) {
pid = pids[i];
}
//printf("PID: %d, Process: %s\n", pids[i], path_buffer);
}
mach_port_name_t port = 0;
if(task_for_pid(mach_task_self(), pid, &port)) {
printf("Run as root!\n");
}
printf("%d\n", port);
return 0;
}
So I got there and now have the mach port of the target pid however I am not sure where to go from here as I have found practically 0 good documentation on the mach_vm methods and anything I try fails. How should I go about doing this?
Related
I'm trying to learn how to multithread with c, and thought that the longest palindromic subsequence problem would be a good place to start.
The idea is that we run two threads and compare their results to find the answer. One thread deals with "odd" subsequences, the other with "even" ones.
Although the code below seems to work, my question is: where in the program should I check for multi-threading errors? It is very new to me so I just need to know what parts may be prone to the issues that multi-threading brings.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
struct str{
char* seq;
int len;
};
void *odd(void* arg){
struct str index = *(struct str*)arg;
int maxAns = 1;
for(int i = 1; i < index.len; i++){
int low = i - 1;
int high = i + 1;
int currMax = 1;
while(low >= 0 && high < index.len && index.seq[low] == index.seq[high]){
low--;
high++;
currMax=currMax+2;
}
if(currMax > maxAns){
maxAns = currMax;
}
}
int* res = malloc(sizeof(int));
*res = maxAns;
free(arg);
return (void*)res;
}
void *even(void* arg){
struct str index = *(struct str*)arg;
int maxAns = 0;
for(int i = 0; i < index.len; i++){
int low = i;
int high = i + 1;
int currMax = 0;
while(low >= 0 && high < index.len && index.seq[low] == index.seq[high]){
low--;
high++;
currMax=currMax+2;
}
if(currMax > maxAns){
maxAns = currMax;
}
}
int* res = malloc(sizeof(int));
*res = maxAns;
free(arg);
return (void*)res;
}
int main(void){
char seq0[] = "aaasaaasadaadsdafa";
int len = sizeof(seq0)/sizeof(seq0[0])-1;
struct str* s0 = malloc(sizeof(struct str));
struct str* s1 = malloc(sizeof(struct str));
s0->seq = (char*)seq0;
s1->seq = (char*)seq0;
s0->len = len;
s1->len = len;
pthread_t t0;
pthread_t t1;
int* res0;
int* res1;
if (pthread_create(&t0, NULL, &odd, s0)!=0){
return 0;
}
if (pthread_create(&t1, NULL, &even, s1)!=0){
return 00;
}
if(pthread_join(t0, (void**)&res0)!=0){
return 1;
}
if(pthread_join(t1, (void**)&res1)!=0){
return 11;
}
if(*res0 > *res1){
printf("%d\n", *res0);
}else{
printf("%d\n", *res1);
}
free(s0);
free(s1);
return 0;
}
I can't understand why if I use
while (tab[i+1] == 0)
{
i+=1;
}
My program hangs
but if I use
while (tab[++i] == 0);
It executes as it should. What am I missing?
Full code:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <limits.h>
#define SIZE 100
typedef struct
{
unsigned int prime;
unsigned int size;
unsigned int *tab;
} shared_data;
void *sieve(void *);
sem_t mutex;
int main()
{
pthread_t tid;
unsigned int tab[SIZE];
sem_init(&mutex, 0, 0);
for (unsigned int i = 0; i < SIZE; i++)
{
tab[i] = i;
}
unsigned int i = 2; //index startowy
shared_data shared = {i, SIZE, tab};
while (i < SIZE)
{
shared.prime = tab[i];
pthread_create(&tid, NULL, sieve, &shared);
sem_wait(&mutex);
while (tab[++i] == 0);
}
pthread_join(tid, NULL); // czekaj az ostatni watek zakonczy dzialanie
sem_destroy(&mutex);
printf("Liczby pierwsze:\n");
for (unsigned int i = 0; i < SIZE; i++)
if (tab[i]) //pomin 0 przy wyswietlaniu
printf("%d | ", tab[i]);
printf("\n");
return 0;
}
void *sieve(void *arg_p)
{
shared_data arg = *(shared_data *)arg_p;
shared_data io = arg;
int unlock_thread = 1;
for (unsigned int i = io.prime + 1; i < io.size; i++)
{
if (io.tab[i] % io.prime == 0)
io.tab[i] = 0;
else if (unlock_thread)
{
sem_post(&mutex);
unlock_thread = 0;
}
}
if (unlock_thread)
sem_post(&mutex);
return NULL;
}
while (tab[i+1] == 0)
{
i+=1;
}
Checks the next element of tab and doesn't change i when it is zero.
This means i won't change to the value where tab[i] becomes zero.
In the other hand,
while (tab[++i] == 0);
First go to the next element of tab and therefore i can be changed to make tab[i] zero.
To separate access to tab and update of i, you can do like this:
do {
i+=1;
} while (tab[i] == 0);
Also note that you must not access (no read nor write) out-of-range elements of arrays. The array tab has only SIZE elements, so the available indices are only 0 to SIZE-1. This means you must not read tab[SIZE]. You should add range check to the loops like this:
while (++i < SIZE && tab[i] == 0);
do {
i+=1;
} while (i < SIZE && tab[i] == 0);
I wrote a multi-thread today. The task of the thread is to write data to a large array. A single thread takes about 0.7s, but it takes more than 20 seconds to write independently and concurrently with two threads. The same operation is under Windows or Multi-process seconds under Linux all are about 0.7s.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/time.h>
#include <sys/types.h>
#define SIZE_IN_MB 256
#define NUM_BYTE (SIZE_IN_MB*1024*1024)
#define NUM_LONG (NUM_BYTE/sizeof(long))
#define CHILD_COUNT 2
#define STEP_SIZE 1 //use to avoid cache,when set to 8
unsigned long Time[CHILD_COUNT];
struct Arg {
unsigned long *data;
int index;
};
unsigned long diffTime(struct timeval *end, struct timeval *start) {
return labs((end->tv_sec - start->tv_sec) * 1000 + (end->tv_usec - start->tv_usec) / 1000);
}
void getTime(struct timeval *t) {
gettimeofday(t, NULL);
}
unsigned long writeData() {
struct timeval start, end;
getTime(&start);
unsigned long *data = (unsigned long *) malloc(NUM_LONG * sizeof(long));
for (int i = 0; i < STEP_SIZE; ++i) {
for (size_t k = i; k < NUM_LONG; k+=STEP_SIZE)
data[k] = 0x5a5a5a5a5a5a5a5a + rand();
}
getTime(&end);
free(data);
return diffTime(&end, &start);
}
void *child(void *arg) {
Time[((struct Arg *) arg)->index] = writeData();
}
void waitAll(pthread_t threads[]) {
for (int i = 0; i < CHILD_COUNT; i++) {
pthread_join(threads[i], NULL);
}
}
void printAverTime(int count) {
unsigned long time = 0;
for (int i = 0; i < count; ++i) {
time += Time[i];
}
printf("Thread: %ld\n", time / count);
}
void thread_test() {
pthread_t threads[CHILD_COUNT];
struct Arg arg[CHILD_COUNT] = {};
for (int i = 0; i < CHILD_COUNT; i++) {
arg[i].index = i;
pthread_create(&threads[i], NULL, child, (void *) &arg[i]);
}
waitAll(threads);
printAverTime(CHILD_COUNT);
}
void process_test() {
int p[CHILD_COUNT][2];
for (int i = 0; i < CHILD_COUNT; ++i) {
pipe(p[i]);
}
for (int i = 0; i < CHILD_COUNT; i++) {
if (fork() == 0) {
unsigned long t = writeData();
write(p[i][1], &t, sizeof(t));
exit(0);
}
}
unsigned long t = 0,tmp= 0;
for (int i = 0; i < CHILD_COUNT; ++i) {
read(p[i][0], &tmp, sizeof(tmp));
t += tmp;
}
printf("Process: %ld\n", t / CHILD_COUNT);
}
int main() {
thread_test();
process_test();
}
The penalty you are paying when using multiple threads is not for writing to memory but for the fact that you are calling rand(), which involves locking, many times in the following nested loops in writeData():
for (int i = 0; i < STEP_SIZE; ++i) {
for (size_t k = i; k < NUM_LONG; k+=STEP_SIZE)
data[k] = 0x5a5a5a5a5a5a5a5a + rand();
}
So you are incurring a huge penalty because for each call to rand() only one thread can get in at a time and all the other threads have to wait and there is overhead to this waiting.
You can fix your code to avoid collisions in the inner loop by using a reentrant form of rand(), such as rand_r() (which is documented at https://man7.org/linux/man-pages/man3/rand.3.html)
unsigned int seed = rand();
for (int i = 0; i < STEP_SIZE; ++i) {
for (size_t k = i; k < NUM_LONG; k+=STEP_SIZE)
data[k] = 0x5a5a5a5a5a5a5a5a + rand_r(&seed);
}
I'm writing a C function to simulate a cache given an address trace. The function works as expected when compiled on my mac using gcc (really clang). gcc --version on my mac returns this:
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 8.1.0 (clang-802.0.42)
When I compile the same program on linux using gcc, the returns are way off, and eC & hC in my program (cache eviction counter and hit counter) are in the hundreds of thousands, when they should be below 10. When typing gcc --version on the linux machine, it returns this:
gcc (Ubuntu 4.9.3-8ubuntu2~14.04) 4.9.3
Here is the program:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <limits.h>
#include <getopt.h>
#include "cachelab.h"
typedef struct{
int v;
int t;
int LRU;
} block;
typedef struct{
block *blocks;
} set;
typedef struct{
set *sets;
} cache;
void simulate(int s, int E, int b, char* file, int* hC, int* mC, int* eC)
{
int numSets = (1 << s);
char operation;
int address;
int size;
int curTag;
int curSet;
int maxLRU = 0;
int curLRU = 0;
int check = 0;
cache c;
set *sets = malloc(sizeof(set) * numSets);
c.sets = sets;
int i = 0;
while(i < numSets)
{
c.sets[i].blocks = malloc(sizeof(block) * E);
for (int j = 0; j < E; j++)
{
c.sets[i].blocks[j].v = 0;
c.sets[i].blocks[j].t = INT_MIN;
c.sets[i].blocks[j].LRU = 0;
}
i++;
}
FILE *f = fopen(file, "r");
while(fscanf(f," %c %x,%d", &operation, &address, &size) != EOF)
{
check = 0;
curTag = ((unsigned int) address) >> (s+b);
curSet = (address >> b) & ((1 << s) - 1);
for (int i = 0; i < E; i++)
{
c.sets[curSet].blocks[i].LRU++;
if(c.sets[curSet].blocks[i].LRU >= maxLRU)
{
maxLRU = c.sets[curSet].blocks[i].LRU;
curLRU = i;
}
if(curTag == c.sets[curSet].blocks[i].t)
{
*hC = *hC + 1;
if (operation == 'M')
{
*hC = *hC + 1;
}
c.sets[curSet].blocks[i].LRU = 0;
check = 1;
}
}
if(check == 0)
{
for(int i = 0; i < E; i++)
{
if(c.sets[curSet].blocks[i].v == 0)
{
*mC = *mC + 1;
if (operation == 'M')
{
*hC = *hC + 1;
}
c.sets[curSet].blocks[i].v = 1;
c.sets[curSet].blocks[i].LRU = 0;
c.sets[curSet].blocks[i].t = curTag;
check = 1;
break;
}
}
}
if(check == 0)
{
*eC = *eC + 1;
*mC = *mC + 1;
if (operation == 'M')
{
*hC = *hC + 1;
}
c.sets[curSet].blocks[curLRU].t = curTag;
c.sets[curSet].blocks[curLRU].v = 1;
c.sets[curSet].blocks[curLRU].LRU = 0;
}
}
}
int main(int argc, char** argv)
{
int hitCount, missCount, evictionCount;
int s, E, b;
char *file;
char opt;
while((opt = getopt(argc,argv,"v:h:s:E:b:t:")) != -1)
{
switch(opt){
case 'v':
break;
case 'h':
break;
case 's':
s = atoi(optarg);
break;
case 'E':
E = atoi(optarg);
break;
case 'b':
b = atoi(optarg);
break;
case 't':
file = optarg;
break;
default:
exit(1);
}
}
simulate(s, E, b, file, &hitCount, &missCount, &evictionCount);
printSummary(hitCount, missCount, evictionCount);
return 0;
}
EDIT:
I understand that this is due to a difference between clang and gcc. Does anyone have any information about how I can go about fixing this discrepancy?
Here is cachelab.c:
/*
* cachelab.c - Cache Lab helper functions
*/
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "cachelab.h"
#include <time.h>
trans_func_t func_list[MAX_TRANS_FUNCS];
int func_counter = 0;
/*
* printSummary - Summarize the cache simulation statistics. Student cache simulators
* must call this function in order to be properly autograded.
*/
void printSummary(int hits, int misses, int evictions)
{
printf("hits:%d misses:%d evictions:%d\n", hits, misses, evictions);
FILE* output_fp = fopen(".csim_results", "w");
assert(output_fp);
fprintf(output_fp, "%d %d %d\n", hits, misses, evictions);
fclose(output_fp);
}
/*
* initMatrix - Initialize the given matrix
*/
void initMatrix(int M, int N, int A[N][M], int B[M][N])
{
int i, j;
srand(time(NULL));
for (i = 0; i < N; i++){
for (j = 0; j < M; j++){
// A[i][j] = i+j; /* The matrix created this way is symmetric */
A[i][j]=rand();
B[j][i]=rand();
}
}
}
void randMatrix(int M, int N, int A[N][M]) {
int i, j;
srand(time(NULL));
for (i = 0; i < N; i++){
for (j = 0; j < M; j++){
// A[i][j] = i+j; /* The matrix created this way is symmetric */
A[i][j]=rand();
}
}
}
/*
* correctTrans - baseline transpose function used to evaluate correctness
*/
void correctTrans(int M, int N, int A[N][M], int B[M][N])
{
int i, j, tmp;
for (i = 0; i < N; i++){
for (j = 0; j < M; j++){
tmp = A[i][j];
B[j][i] = tmp;
}
}
}
/*
* registerTransFunction - Add the given trans function into your list
* of functions to be tested
*/
void registerTransFunction(void (*trans)(int M, int N, int[N][M], int[M][N]),
char* desc)
{
func_list[func_counter].func_ptr = trans;
func_list[func_counter].description = desc;
func_list[func_counter].correct = 0;
func_list[func_counter].num_hits = 0;
func_list[func_counter].num_misses = 0;
func_list[func_counter].num_evictions =0;
func_counter++;
}
You forgot to initialize the counters and flags so they start at undefined values. The following lines:
int hitCount, missCount, evictionCount;
int s, E, b;
should be:
int hitCount = 0, missCount = 0, evictionCount = 0;
int s = 0, E = 0, b = 0;
It just happens that the initial values happen to be lower on the mac so you're not getting correct results on the mac either (at least not guaranteed since the initial value is undefined).
Hi I want to read some information in a struct that i wrote in file with fwrite but there's a problem I can't extract these information. I got 2 file
tttfs.h :
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
typedef struct _disk disk;
typedef struct _block block;
struct _block{
uint8_t *unBlock;
};
struct _disk{
int id;
block *diskBlock;
};
tfs_create.c :
#include "tttfs.h"
uint8_t little[4];
int tttfs_create(int size, char *name);
void inttolitend(uint32_t x, uint8_t* lit_int);
int main(){
tttfs_create(7, "disk.tfs");
int f = 0;
if((f=open("disk.tfs",O_RDONLY)) < -1) //I took this from an example.
return 1;
disk *d = malloc(sizeof(disk)); //Create a disk
d->diskBlock = malloc(1024); //The block where I want to write the information from the file.
lseek(f,0,SEEK_SET);//I want to read from the beginning
read(f,d->diskBlock,1024); //I write all the information from the beginning to 1024th byte of my file
int i;
for(i=0; i<4; i++){
printf("%d\n", (uint8_t)&d->diskBlock[i]);//print my result.
}
}
int tttfs_create(int size, char *name){
FILE *f = NULL;
if ((f = fopen(name, "wb"))!=NULL) /** si ouverture ok **/
{
disk *d = malloc(sizeof(disk));
d->diskBlock = malloc(sizeof(block) * size);
d->id = 1;
int i;
for(i = 0; i<size; i++){
d->diskBlock[i].unBlock = malloc(sizeof(uint8_t) * 1024);
}
inttolitend(size, little);
for(i = 0; i<4; i++){
d->diskBlock[0].unBlock[i] = little[i];
}
for(i = 0; i<size; i++){
fwrite(&d->diskBlock[i],sizeof(block),1,f);
}
}
else
printf("Erreur\n\n");
return 0;
}
void inttolitend(uint32_t x, uint8_t* lit_int){
lit_int[3] = (uint8_t)x / (256*256*256);
lit_int[2] = (uint8_t)(x % (256*256*256)) / (256*256);
lit_int[1] = (uint8_t)((x % (256*256*256)) % (256*256)) / 256;
lit_int[0] = (uint8_t)((x % (256*256*256)) % (256*256)) % 256;
}
With this I create a disk with 7 block and I write all 7 block in my file. In my first block I wrote the size of my disk (7) in little endian. So block[0] = 00, block[1] = 00, block[2] = 01, block[3] = 11 or something like that.
But when I print my result I get :
0
8
16
24
Not what I expected I try without readand i got the same result. So my programm didn't write the information from the disk. Or there's a problem when I write my block in the disk ?
i can not be so sure what you want exactly but this should work
#define BLOCK_BUFF_SIZE (1024*sizeof(block))
int tttfs_create(int size, char *name);
int tttfs_load(char *fname, disk *pdisk)
void inttolitend(uint32_t x, uint8_t* lit_int);
int tttfs_load(char *fname, disk *pdisk){
int fd;
unsigned int n;
int i;
fd = open("disk.tfs",_O_RDONLY);
if(fd==-1){
perror("tttfs_load.open");
return -1;
}
n=lseek (fd,0,SEEK_END);
lseek(fd,0,SEEK_SET);
if(n==(unsigned int)-1){
close(fd);
return -1;
}
if(n){
n/=(BLOCK_BUFF_SIZE);
pdisk->diskBlock=malloc(n*sizeof(block));
for(i=0;i<n;i++){
pdisk->diskBlock[i].unBlock=malloc(BLOCK_BUFF_SIZE);
read(fd,pdisk->diskBlock[i].unBlock,BLOCK_BUFF_SIZE);
}
}
close(fd);
return n;
}
int main(){
unsigned int n;
disk d;
int i;
tttfs_create(7, "disk.tfs");
n=tttfs_load("disk.tfs",&d);
if(!n || n==(-1)) return -1;
for(i=0; i<4; i++){
printf("%d\n", (uint8_t)(d.diskBlock->unBlock[i]));//print my result.
}
}
int tttfs_create(int size, char *name){
FILE *f = NULL;
disk d;
int i;
if (!(f = fopen(name, "wb"))) {
perror("tttfs_create:open()");
return 0;
}
d.diskBlock = malloc(sizeof(block) * size);
d.id = 1;
for(i = 0; i<size; i++){
d.diskBlock[i].unBlock = malloc(BLOCK_BUFF_SIZE);
}
inttolitend(size, (uint8_t*)(d.diskBlock->unBlock));
for(i=0;i<size;i++){
fwrite(d.diskBlock[i].unBlock ,BLOCK_BUFF_SIZE,1,f);
}
return 1;
}
void inttolitend(uint32_t x, uint8_t* lit_int){
lit_int[3] = ((x<<24) & 0xff);
lit_int[2] = ((x<<16) & 0xff);
lit_int[1] = ((x<<8) & 0xff);
lit_int[0] = ((x<<0) & 0xff);
}