I'm trying to get a pthread example to run on my Windows 10 64-bit machine
I'm compiling using the most recent version of cygwin (64-bit), compiling the code as
gcc thread.c -pthread -o main.exe
which compiles with no error. thread.c looks like so:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
void *worker_thread(void *arg)
{
printf("This is worker_thread()\n");
pthread_exit(NULL);
}
int main()
{
int a = fork();
if (a == 0) {
printf("child a=%d\n", a);
pthread_t my_thread;
int ret = pthread_create(&my_thread, NULL, &worker_thread, NULL);
printf("ret = %d\n", ret);
} else {
printf("parent a=%d\n", a);
int status;
wait(&status);
printf("status = 0x%X (%d)\n", status, status);
}
return 0;
}
On my machine, the output looks like so:
parent a=10868
child a=0
status = 0x7F00 (32512)
which is happening because pthread_create is causing my code to exit.
According to this, this error means:
"It didn't die from a signal, a core dump wasn't produced, and it exited with code 127 (0x7F).
What 127 means is unclear, which is why it should accompanied by an error message."
On my windows 8 64-bit machine, the code runs as expected, with the same build of cygwin (64-bit) installed, and returns this output.
parent a=26744
child a=0
ret = 0
this is worker_thread()
status 0x0 (0)
Any help would be much appreciated.
Related
I have written quite a lot of threaded code on HP-UX and even SUSE and that works perfectly. But it does not work on Red Hat. This is my machine:
Linux version 3.10.0-1062.18.1.el7.x86_64 (Red Hat 4.8.5-39)
Red_Hat_Enterprise_Linux-Release_Notes-7-en-US-7-2.el7.noarch
redhat-release-server-7.7-10.el7.x86_64
I wrote a simple test program, thr_ex.c:
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
void *funny(void *);
void *funny(s)
void *s;
{
int fd;
fd = creat("/tmp/funny_func", 0600);
write(fd, s, strlen((char *) s));
close(fd);
}
int main()
{
int return_value;
pthread_t thread_id;
pthread_attr_t thread_attr;
pthread_attr_init(&thread_attr);
pthread_attr_setscope(&thread_attr, PTHREAD_SCOPE_SYSTEM);
pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED);
return_value = pthread_create(&thread_id, &thread_attr, funny, (void *) "Here I am\n");
printf("Return value == %d\n", return_value);
printf("Thread id == %hu\n", thread_id);
exit(0);
} /* End main. */
Compiling, building:
gcc -pthread -s -o thr_ex thr_ex.c
Running:
./thr_ex
Return value == 0
Thread id == 5888
But no file gets created under /tmp.
strace -f shows no creat() or write() ( except from the printf's in main () ).
However, strace -f do show, for example:
strace: Exit of unknown pid 64574 ignored
I have tried even simpler code where the thread only runs a printf() and a fflush(), with no thread attributes and no argument to the function. Still nothing happens.
Insert before the return statement or exit( 0 ) statement in main
pthread_exit( NULL );
Otherwise the created thread can have no time to be executed because the process will end.
The program is basically checking for how fcntl function works. The main program(Pm.c) creates a pipe and 3 child processes by forking. It then does necessary fcntl function on the pipe and then writes to it.
The child processes terminate after receiving the signal from pipe in ubuntu virtual box but they don't receive any signal in the ubuntu windows app.
Pm.c -
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <string.h>
#include <signal.h>
int main()
{
int c = getpid(), c1, c2, c3;
int pp[2];
pipe(pp);
char *args[1];
args[0] = NULL;
if((c1 = fork()) == 0)
execvp("./p1", args);
if((c2 = fork()) == 0)
execvp("./p2", args);
if((c3 = fork()) == 0)
execvp("./p3", args);
setpgid(0, 0);
setpgid(c1, c);
setpgid(c2, c);
setpgid(c3, c);
printf("%d %d %d %d\n", c, c1, c2, c3);
printf("%d %d %d %d\n", getpgid(c), getpgid(c1), getpgid(c2), getpgid(c3));
int gid = getpgid(c);
sleep(1);
fcntl(pp[0], F_SETFL, O_ASYNC);
fcntl(pp[0], __F_SETSIG, SIGUSR1);
fcntl(pp[0], F_SETOWN, -gid);
write(pp[1], "bruh ", 4);
close(pp[1]);
wait(NULL);
return 0;
}
P1.c (P2.c and P3.c is similar to this)
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
int pr = 1;
void hdfn(int x)
{
printf("Recieved signal from pm\n");
pr--;
}
int main()
{
signal(SIGUSR1, hdfn);
printf("P1 is running\n");
while(pr);
return 0;
}
Here's the output in Ubuntu virtual Box. The program terminates and is the correct output -
1846 1847 1848 1849
1846 1846 1846 1846
P1 is running
P2 is running
P3 is running
Recieved signal from pm
Recieved signal from pm
Recieved signal from pm
User defined signal 1
output on ubuntu windows app. (Program doesn't terminate) -
26 27 28 29
26 26 26 26
P1 is running
P2 is running
P3 is running
Can someone please tell why there's a difference in output and how I can get the correct output on ubuntu app.
This is because fcntl doesn't exist on windows subsystem for linux. I'd expect your "ubuntu windows app" is this app. Your code is compiling because headers exist but fcntl is not supported. See this github issue.
I installed Arch Arm onto an Rpi3, then rsync'd sysroot to an x86_64 Arch Linux installed on a Lenovo thinkpad.
I then installed the arm-linux-gnueabihf Linaro cross compiler
To avoid any problems I used absolute paths in compilation:
/home/sameh/Rpi/Compiler/gcc-linaro-7.2.1-2017.11-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc\
--sysroot=/home/sameh/Rpi/Arch/ArmV7/root\
-o stress stress.c -lm
The code compiles fine, however when I execute it on the Rpi3 it has no output.
It doesn't freez the Pi, I can ps aux and see the child processes created by fork().
But none of the debug statements are printed and none of the processes exit.
Edit
This code is based on the stress library. For an MCVE I minimized it to only the hogcpu function
#include <ctype.h>
#include <errno.h>
#include <libgen.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <time.h>
#include <unistd.h>
#include <sys/wait.h>
int hogcpu (void);
int
hogcpu (void)
{
for(int i=0; i < 1000000; i++)
sqrt (rand ());
return 0;
}
int main()
{
struct timespec start, end;
double cpu_time_used;
int pid, children = 0, retval = 0;
long forks;
int do_dryrun = 0;
long long do_backoff = 3000;
long long do_cpu = 1;
long long backoff, timeout = 0;
/* Calculate the backoff value so we get good fork throughput. */
backoff = do_backoff * forks;
clock_gettime(CLOCK_REALTIME, &start);
while ((forks = (do_cpu + do_io + do_vm + do_hdd)))
{
if (do_cpu)
{
switch (pid = fork ())
{
case 0: /* child */
alarm (timeout);
usleep (backoff);
exit (hogcpu ());
case -1: /* error */
break;
default:
++children;
}
--do_cpu;
}
}
/* Wait for our children to exit. */
while (children)
{
int status, ret;
if ((pid = wait (&status)) > 0)
{
--children;
if (WIFEXITED (status))
{
if ((ret = WEXITSTATUS (status)) == 0)
{
printf( "<-- worker %i returned normally\n", pid);
}
else
{
printf( "<-- worker %i returned error %i\n", pid, ret);
++retval;
printf( "now reaping child worker processes\n");
if (signal (SIGUSR1, SIG_IGN) == SIG_ERR)
printf( "handler error: %s\n", strerror (errno));
if (kill (-1 * getpid (), SIGUSR1) == -1)
printf( "kill error: %s\n", strerror (errno));
}
}
}
}
clock_gettime(CLOCK_REALTIME, &end);
cpu_time_used = (end.tv_nsec = start.tv_nsec) / 1000000000.0;
/* Print final status message. */
if (retval)
{
printf( "failed run completed in %.2f s\n", cpu_time_used);
}
else
{
printf( "successful run completed in -- %.2f s\n", cpu_time_used);
}
exit (retval);
}
I can successfully compile and execute it on the the Pi with:
[alarm#control ~]$ gcc stress.c -o stress -lm
[alarm#control ~]$ ./stress
<-- worker 16834 returned normally
<-- worker 16835 returned normally
<-- worker 16836 returned normally
successful run completed in -- 0.90 s
However, when cross compiled and transferred to the Pi, the behavior described above is what I am seeing.
Note
This may well have to do with the clock_gettime call. When I replace this with a clock() function call, I can compile and run it on the laptop, but compiling on the Pi with gcc has the same behavior above.
When using clock_gettime and compiling on the Pi, it works fine.
The issue here was how the long forks; variable was initialized. I am not well versed in compilers, but because forks was not initialized, the calculation backoff = do_backoff * forks; resulted in a random negative number.
This blocked the call usleep (backoff); from finishing. So initializing forks to 1 fixed the problem.
I would have thought that forks should have been initialized to 0 by the compiler as past of the bss_data so I am not sure why it didn't. Probably need more research into that part, but the code executes fine now with cross compiling.
This is my code, I compiled it with:
gcc thread.c -lpthread
It didn't print any error or warning. But when I run it, the program doesn't print anything.
Platform: Ubuntu 11.10 64 bit gcc 4.6.1
Exit status :0
When I debug it, I found it prints hello as I expected.
This is my code:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
void *loopPrint(void *ptr)
{
char *p = (char *)ptr;
while (1)
{
printf("%s\n", p);
}
}
void *pClock(void *ptr)
{
sleep(3);
exit(0);
}
int main()
{
pthread_t showMsg, clock;
int main_pth, wait_pth;
char *msg = "Hello";
main_pth = pthread_create(&showMsg, NULL, loopPrint, (void *)msg);
wait_pth = pthread_create(&clock, NULL, pClock, NULL);
pthread_join(main_pth, NULL);
pthread_join(wait_pth, NULL);
return 0;
}
pthread_join(main_pth, NULL);
This is wrong, pthread_join takes a pthread_t as an argument. Replace with:
pthread_join(showMsg, NULL);
(Same for the other one.)
And do check the return values of these calls, they can and do fail.
And BTW, you're missing #include <unistd.h> for the sleep call.
main_pth etc is the error return of pthread_create and not the thread id. Wait ("join") for showMsg and clock.
For some reasons I cannot get anything to come out of task_for_pid()
I can't find very much information but what I am trying to do it attach to another process and search its memory, but every time I try to use task_for_pid, I get the same (os/kern) failure error.
#include <stdio.h>
#include <mach/mach_traps.h>
#include <mach/mach_init.h>
int main(int argc, char* argv[])
{
mach_port_name_t task;
printf("%d\n", argv[1]);
int pid = atoi(argv[1]);
printf("%d\n%d\n", pid, current_task());
int error = task_for_pid(2055, 24269, &task);
printf("%x\n", task);
if (error)
{
printf("task_for_pid return error:\n %s\n", mach_error_string(error));
} else {
printf("Get the process %d's task port : %x\n", pid, task);
}
return 0;
}
Output looks like:
gcc -o test test.c;./test 24269
803206115
24269
2055
0
task_for_pid return error:
(os/kern) failure
Any idea's as to why im not getting a task, ever?
I am running it as root.
As Adam Rosenfield said, it does say in the header that it is obsolete, but if thats true, could I still compile and run it with an older version of the toolchain? or what has it been replaced with? does anyone know?
Are you sure you are running as root?
Are you sure the process 24269 is still running?
I have no problem running this code (with sudo) on Mac OS X 10.6.8 with any running process:
#include <stdio.h>
#include <stdlib.h>
#include <mach/mach_traps.h>
#include <mach/mach_init.h>
#include <mach/mach_error.h>
int main(int argc, char* argv[])
{
task_t task;
pid_t pid = argc >= 2 ? atoi(argv[1]) : 1;
kern_return_t error = task_for_pid(current_task(), pid, &task);
printf("%d -> %x [%d - %s]\n", pid, task, error, mach_error_string(error));
return error;
}
For example, here is my result with pid 182 (Dock)
$ sudo ./task_for_pid 182
182 -> 413 [0 - (os/kern) successful]