illegal instruction on exp_expectl with AIX 64 bit - c

Please take a look at this simple utility program. It works fine with AIX when compiled to 32 bit using libexpect5.42 provided by the operating system.
However, when linking with a 64 bit of libexpect which we manually compiled, we are getting an illegal instruction error on the call to exp_expectl(). Any ideas are welcomed.
#include <stdio.h>
#include <stdlib.h>
#include <expect.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
int
main (int argc, char** argv, char** arge)
{
int returnValue = 0;
int iFd = 0;
int res = 0;
exp_loguser = 1;
exp_timeout = 5;
exp_is_debugging = 0;
printf("spawning process without argument\n");
iFd = exp_spawnl ("ls", "ls",(char*)0 );
printf ("spawned\n");
printf ("iFd = %d\n", iFd);
if (iFd < 0)
{
printf ("Return %d\n",iFd);
}
else
{
res = exp_expectl (iFd, exp_glob,"ls", 0, exp_end);
printf ("Return %d \n",res);
}
return iFd;
}

Related

Why do I keep getting segmentation fault in my C program

I've been trying to implement thread synchronization on C. However, I keep getting the segmentation fault when my invoke the function that I want the thread to execute. So anyone can suggest the solution on for this problem?
Here is my code
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#define N 5
#define M 3
#define LEFT (robot_id - 1) % N
#define RIGHT (robot_id + 1) % N
pthread_t robots_id[N];
sem_t simulations[M];
pthread_mutex_t sever_mutex;
void Learning(int robot_id)
{
printf("learning robot = %d\n", robot_id);
}
void *robotAct(void *id)
{
int *robot_id = id;
printf("robot id = %d\n", robot_id);
Learning(*robot_id);
}
int main(int argc, char *argv[])
{
int E, T;
E = atoi(argv[1]);
T = atoi(argv[2]);
printf("Initializing Robot!\n");
//Initializes the simulations
for (int i = 0; i < M; i++)
{
sem_init(&simulations[i], 0, 0);
}
//Initializes the robots
for (int i = 0; i < N; i++)
{
printf("Robot %d is created\n", i + 1);
pthread_create(&robots_id[i], NULL, robotAct, (void *)i + 1);
}
sleep(T);
printf("Terminating Robots\n");
for (int i = 0; i < N; i++)
{
pthread_cancel(robots_id[i]);
}
printf("Termination is completed!\n");
printf("-------Report-------------\n");
//getReport();
return 0;
}
Here is my result that I keep getting
Initializing Robot!
Robot 1 is created
Robot 2 is created
Robot 3 is created
robot id = 1
robot id = 2
Robot 4 is created
robot id = 3
[1] 54477 segmentation fault ./project 5 10
The main issue is explained in my comment:
You're not passing a valid pointer to the thread function. You sort of, mostly, almost get away with the misuse of it in the printf() call in robotAct(); you emphatically do not get away with it in the call to Learning() where you dereference the invalid non-pointer.
A solution is to create an array of integers in the main program which holds robot ID numbers (int id[N];). Then, initialize each element and pass &id[i] to pthread_create().
You should not print addresses with the %d format (even though it works on 32-bit systems; it does not work on 64-bit systems). The correct technique is to use %p to format the address. Or, in this case, print the integer and not the address using *robot_id.
The code that follows has minimal adaptations to the original code and has not been compiled or tested (there could be problems outside the lines changed):
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#define N 5
#define M 3
#define LEFT (robot_id - 1) % N
#define RIGHT (robot_id + 1) % N
pthread_t robots_id[N];
sem_t simulations[M];
pthread_mutex_t sever_mutex;
void Learning(int robot_id)
{
printf("learning robot = %d\n", robot_id);
}
void *robotAct(void *id)
{
int *robot_id = id;
printf("robot id = %d\n", *robot_id); // Changed
Learning(*robot_id);
return 0; // Added
}
int main(int argc, char *argv[])
{
int E, T;
int id[N]; // Added
E = atoi(argv[1]);
T = atoi(argv[2]);
printf("Initializing Robot!\n");
//Initializes the simulations
for (int i = 0; i < M; i++)
{
sem_init(&simulations[i], 0, 0);
}
//Initializes the robots
for (int i = 0; i < N; i++)
{
printf("Robot %d is created\n", i + 1);
id[i] = i + 1; // Added
pthread_create(&robots_id[i], NULL, robotAct, &id[i]); // Changed
}
sleep(T);
printf("Terminating Robots\n");
for (int i = 0; i < N; i++)
{
pthread_cancel(robots_id[i]);
}
printf("Termination is completed!\n");
printf("-------Report-------------\n");
//getReport();
return 0;
}
Avoid using pthread_cancel() for ending the threads; the threads should terminate under control. For example, there might be a flag that you set in the main thread to indicate that the threads should cease, and they'd check that periodically. Normally, pthread_join() is used to clean up the completed threads.
For future posts, please read about how to create an MCVE (Minimal, Complete, Verifiable Example). There are parts of the code shown that are not relevant to the problem — the mutex and the semaphores, for example, are not really used.

System call poll() does not work on Ubuntu Kylin 16.04 32 bit version, but works on Fedora 21 64 bit

This is a short version of my code: I have a 64 bit fedora 21 on which the code works fine. However on my other 32bit machine on which I have installed ubuntu Kylin 16.04 32 bit version, poll does not return when text is entered on stdin, it just stays blocked. When I hit Ctrl-C in gdb after the text is entered, and then try executing next command it works... Is this a bug of ubuntu 32 bit version or I have to use poll differently on 32 bit version?
#include <sys/ioctl.h>
#include <sys/poll.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int
main(int argc, char **argv)
{
int sockfd;
int const myOPEN_MAX=100,MAXLINE=4096;
struct pollfd client[myOPEN_MAX];
int maxi,nready,n;
char buf[4096];
client[0].fd = fileno(stdin);
client[0].events = POLLRDNORM;
for (int i = 1; i < myOPEN_MAX; i++){
client[i].fd = -1; /* -1 indicates available entry */
}
maxi = 1; /* max index into client[] array */
printf("enter something\n");
for ( ; ; ) {
nready = poll(client, maxi+1, -1);
for (int i = 0; i <= maxi; i++) { /* check all clients for data */
if ( (sockfd = client[i].fd) < 0)
continue;
if (client[i].revents & (POLLRDNORM | POLLERR)) {
if ( (n = read(sockfd, buf, MAXLINE)) > 0) {
if (i == 0) { //stdin
printf("works\n");
return 0;
}
if (--nready <= 0)
break; /* no more readable descriptors */
}
}
}
}
return 0;
}

About FD_SET and fd_set in linux

My os is 64bits Centos6.4. I have a question about how to fd_set manage FD_SET add the fd.Follow code is case:
fd_set my_set;
FD_SET(31, &my_set);
Then, I show my_set.fds_bits[...].The my_set.fds_bits[0] is equal to 0x0000000080000000, my_set.fds_bits[1~...] is zero.I can understand the result.But I also write an case,Follow code:
fd_set my_set;
FD_SET(63, &my_set);
I show my_set.fds_bits[...].The my_set.fds_bits[0] is equal to 0x0.In my opinion, the result should be my_set.fds_bits[0] is equal to 0x8000000000000000.I really don't understand why sencond result is 0x0. Doesn't fd that is equal to 63 have a state in my_set.
Here is full testing code:
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/socket.h>
#include <resolv.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/time.h>
#include <pthread.h>
#define BUFSIZE 1024
void printFDSET(fd_set target_sets)
{
int uIndex = 0;
int model_num = __NFDBITS;
for(uIndex = 0; uIndex < 10/*FD_SETSIZE/model_num*/; uIndex++)
{
printf("0x%016x\t", target_sets.fds_bits[uIndex]);
if(uIndex % 4 == 3)
printf("\n");
}
printf("\n");
return;
}
int main(int argc, char* argv[])
{
fd_set my_set;
FD_ZERO(&my_set);
printf("sizeof(long int) = %d\n", sizeof(long int));
printf("FD_SETSIZE = %d\n", FD_SETSIZE);
printf("size = %zu\n", sizeof __FDS_BITS(&my_set)[0]);
printf("\n\n");
int unfd = 31;
FD_SET(unfd, &my_set);
printf("%d is added to my_set:\n", unfd);
printFDSET(my_set);
printf("\n\n");
FD_CLR(unfd, &my_set);
unfd = 63;
printf("%d is added to my_set:\n", unfd);
FD_SET(unfd, &my_set);
printFDSET(my_set);
return 0;
}
Doesn't fd that is equal to 63 have a state in my_set.
It has. You just didn't correctly print the value, because you forgot the length modifier l in the printf format string.
printf("0x%016lx\t", __FDS_BITS(&target_sets)[uIndex]);
You probably compiled your code as 32 bit. set.fds_bits is an array of long int. Check the value of my_set.fds_bits[1]

c cygwin- abored(core dumped)

I have tried for a long time and cannot figure out where this 'core dumped' is coming from. I am using c on cygwin. Commenting out the threads gets rid of the problem but commenting out the entire code in the thread does nothing. Could this have something to do with the calling of the thread?? It appeared to be working then this suddenly happened. I have deleted most of the code and this is what is left-
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <stdint.h>
#include <pthread.h>
#include <string.h>
typedef enum {true=1, false=0} bool;
void *piThread(void *arg);
int finished;
int main(int argc, char *argv[])
{
int i;
int threads;
bool display = false;
long double pI = 0.0;
void *status = malloc(sizeof(int));
pthread_t thread_id[threads];
if(argc < 2) {printf("not enough arguments"); exit(1);
}else threads = atoi(argv[1]);
if(argc == 3)
if (strcmp(argv[2], "b") == 0)
display = true;
for(i=0; i<threads; i++)
{
pthread_create(&thread_id[i], NULL, piThread, NULL);
pthread_join(thread_id[i], &status);
printf("pi: %Lf\n", pI);
}
return 0;
}
void *piThread(void *arg)
{
int number = 0;
number = 74;
pthread_exit((void*)number);
}
This is causing an aborted error.
Stack trace:
Frame Function Args
0028A6A4 76821184 (000000D0, 0000EA60, 00000000, 0028A7D8)
0028A6B8 76821138 (000000D0, 0000EA60, 000000A4, 0028A7B4)
0028A7D8 610DBE29 (00000000, FFFFFFFE, 77403B23, 77403B4E)
0028A8C8 610D915E (00000000, 0028A918, 00000001, 00000000)
0028A928 610D962E (76D709CD, 7427AED9, 00000003, 00000006)
0028A9D8 610D9780 (000011E8, 00000006, 002B002B, 800483D8)
0028A9F8 610D97AC (00000006, 0028CE80, FFFDE000, 00000000)
0028AA28 610D9A85 (000000D0, 0028ABF0, 0028AA58, 610FA223)
End of stack trace
I have no idea what is wrong!!
command line is-
gcc pi.exe 100
any combination ABOVE 26 causes this fault.
Thank you for any insight
You are allocating thread_id before 'threads' is defined. This should fix that problem at least.
if(argc < 2) {printf("not enough arguments"); exit(1);
}else threads = atoi(argv[1]);
pthread_t thread_id[threads];

Get other process' argv in OS X using C

I want to get other process' argv like ps.
I'm using Mac OS X 10.4.11 running on Intel or PowerPC.
First, I read code of ps and man kvm, then I wrote some C code.
#include <kvm.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/sysctl.h>
#include <paths.h>
int
main(void) {
char errbuf[1024];
kvm_t *kd = kvm_openfiles(_PATH_DEVNULL, NULL, _PATH_DEVNULL, O_RDONLY, errbuf);
int num_procs;
if (!kd) { fprintf(stderr, "kvm_openfiles failed : %s\n", errbuf); return 0; }
struct kinfo_proc *proc_table = kvm_getprocs(kd, KERN_PROC_ALL, 0, &num_procs);
for (int i = 0; i < num_procs; i++) {
struct kinfo_proc *pproc = &proc_table[i];
char **proc_argv = kvm_getargv(kd, pproc, 0);
printf("%p\n", proc_argv);
}
kvm_close(kd);
return 0;
}
When ran on PowerPC, kvm_getargv() always returned NULL. When ran
on Intel, kvm_openfiles() failed with error /dev/mem: No such file
or directory.
Of cource, I know about permission.
Second, I tried sysctl.
#include <sys/sysctl.h>
#include <stdio.h>
#include <stdlib.h>
#define pid_of(pproc) pproc->kp_proc.p_pid
int
main(void) {
int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0 };
int buffer_size;
sysctl(mib, 4, NULL, &buffer_size, NULL, 0);
struct kinfo_proc *result = malloc(buffer_size);
sysctl(mib, 4, result, &buffer_size, NULL, 0);
int num_procs = buffer_size / sizeof(struct kinfo_proc);
for (int i = 0; i < num_procs; i++) {
struct kinfo_proc *pproc = result + i;
int mib[3] = { CTL_KERN, KERN_PROCARGS, pid_of(pproc) }; // KERN_PROC_ARGS is not defined
char *proc_argv;
int argv_len;
sysctl(mib, 3, NULL, &argv_len, NULL, 0);
proc_argv = malloc(sizeof(char) * argv_len);
sysctl(mib, 3, proc_argv, &argv_len, NULL, 0);
fwrite(proc_argv, sizeof(char), argv_len, stdout);
printf("\n");
free(proc_argv);
}
return 0;
}
By fwrite, I got argv[0] but argv[1..] are not (environment variables
are printed out.)
There is no more way to do it?
In 10.6, KERN_PROCARGS2 is available: https://gist.github.com/770696
This way is used from ps, procfs on MacFUSE, etc.
I've actually been needing the same thing for a Python library I'm writing, and in my searching I came across another Python lib (PSI) that implements this in C code. It's part of the python module code for listing processes and includes listing the arguments for each process as well. You could take a look at the source code for that for a working example:
darwin_process.c - scroll down to set_exe() for the relevant code
Note: the site is really slow so you'll have to be a bit patient while it loads.

Resources