fork variables randomly change - memory

I want to use execvp to run commands through my program. The user is prompted for a command (exits on eof).
Once the program has a command it forks a child process to process the command while the parent waits for the child to finish.
I'm tokenizing the input to store it in a char* array which is kept track of by variable 'i'.
Except 'i' keeps changing its value with each iteration of the while loop.
sample input: /bin/ls -l
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <string.h>
#define BUFFER 1024
int main(){
pid_t p;
char* paramList[] = {};
char input[BUFFER];
int i = 0;
char* segments;
printf(">");
while(fgets(input, BUFFER, stdin) != NULL){
if((p = fork()) == 0){
printf("Executing: %s\n", input);
i = 0;
segments = strtok(input, " ");
paramList[i] = segments;
printf("%s%d\n", paramList[i], i);
i++;
while(segments != NULL){
segments = strtok(NULL, " ");
paramList[i] = segments;
printf("%s%d\n", segments, i);
i++;
}
paramList[i] = NULL;
execvp(paramList[0], paramList);
}else{
printf(">");
waitpid(p, NULL, 0);
}
}
return 0;
}

You're not declaring a size for paramList, but you're giving it an empty initializer list; thus paramList has zero elements. And then you're writing more than zero elements into it, overflowing onto other local variables (like i).

Related

pthread_t declarations need to be global?

[Edited and added reprex] When I put the declarations below in the beginning of the main() function, the behavior of the threads is erratic and incorrect. When I make these declarations global, or not the first declarations in main(), everything works fine. I'm using mingw-w64 on Windows 10.
pthread_t thr1, thr2, thr3;
Below is the program, it spawns three threads to read integers from three different text files and add them all to a single global variable. The call to pthread_join() for thr3 always fails with error code 3, and the final result of sum is different in different runs. But it all works fine if the pthread_t declarations are in a different location. I hope this is short enough it's less than 70 lines including whitespace.
#include <stdlib.h>
#include <pthread.h>
#include <stdio.h>
long sum = 0;
pthread_mutex_t sumLock = PTHREAD_MUTEX_INITIALIZER;
void* thrFunc(void* arg)
{
char curLine[50];
FILE *inFile = fopen((char*)arg, "r");
long curNum;
if (!inFile) {
printf("Error opening input file %s\n", arg);
pthread_exit((void*)1);
}
while (fgets(curLine, sizeof(curLine), inFile)) {
curNum = strtol(curLine, 0, 0);
pthread_mutex_lock(&sumLock);
sum += curNum;
pthread_mutex_unlock(&sumLock);
}
fclose(inFile);
pthread_exit((void*)0);
}
int main(void)
{
pthread_t thr1, thr2, thr3;
long threadResult;
int err;
if (pthread_create(&thr1, 0, thrFunc, (void*)"C:\\Users\\paulc\\long1.txt")) {
printf("Failed to create thread thr1\n");
exit(1);
}
if (pthread_create(&thr2, 0, thrFunc, (void*)"C:\\Users\\paulc\\long2.txt")) {
printf("Failed to create thread thr2\n");
exit(1);
}
if (pthread_create(&thr3, 0, thrFunc, (void*)"C:\\Users\\paulc\\long3.txt")) {
printf("Failed to create thread thr3\n");
exit(1);
}
if (err = pthread_join(thr1, (void**)&threadResult)) {
printf("failed to join thr1, error code = %d\n", err);
}
if (err = pthread_join(thr2, (void**)&threadResult)) {
printf("failed to join thr2, error code = %d\n", err);
}
if (err = pthread_join(thr3, (void**)&threadResult)) {
printf("failed to join thr3, error code = %d\n", err);
}
printf("Total: %ld\n", sum);
}

is it safe to have two lua thread run parallel on the same lua state without concurrent execution?

we are developing game server using lua.
the server is single threaded, we'll call lua from c++.
every c++ service will create a lua thread from a global lua state which is shared by all service.
the lua script executed by lua thread will call a c api which will make a rpc call to remote server.
then the lua thread is suspened, because it's c function never return.
when the rpc response get back, we'll continue the c code ,which will return to the lua script.
so, we will have multiple lua thread execute parallel on a same global lua state, but they will never run concurrently. and the suspend is not caused but lua yield function, but from the c side.
is it safe to do something like this?
#include <stdio.h>
#include <stdlib.h>
#include <ucontext.h>
#include "lua/lua.hpp"
static ucontext_t uctx_main, uctx_func1, uctx_func2;
lua_State* gLvm;
int gCallCnt = 0;
static int proc(lua_State *L) {
int iID = atoi(lua_tostring(L, -1));
printf("begin proc, %s\n", lua_tostring(L, -1));
if(iID == 1)
{
swapcontext(&uctx_func1, &uctx_main);
}
else
{
swapcontext(&uctx_func2, &uctx_main);
}
printf("end proc, %s\n", lua_tostring(L, -1));
return 0;
}
static void func1(void)
{
gCallCnt++;
printf("hello, func1\n");
lua_State*thread = lua_newthread (gLvm);
lua_getglobal(thread, "proc");
char szTmp[20];
sprintf(szTmp, "%d", gCallCnt);
lua_pushstring(thread, szTmp);
int iRet = lua_resume(thread, gLvm, 1);
printf("lua_resume return:%d\n", iRet);
}
static void func2(void)
{
gCallCnt++;
printf("hello, func2\n");
lua_State*thread = lua_newthread (gLvm);
lua_getglobal(thread, "proc");
char szTmp[20];
sprintf(szTmp, "%d", gCallCnt);
lua_pushstring(thread, szTmp);
int iRet = lua_resume(thread, gLvm, 1);
printf("lua_resume return:%d\n", iRet);
}
int main(int argc, char *argv[]){
int iRet = 0;
gLvm = luaL_newstate();
luaL_openlibs(gLvm);
lua_pushcfunction(gLvm, proc);
lua_setglobal(gLvm, "proc");
char func1_stack[16384];
char func2_stack[16384];
getcontext(&uctx_func1);
uctx_func1.uc_stack.ss_sp = func1_stack;
uctx_func1.uc_stack.ss_size = sizeof(func1_stack);
uctx_func1.uc_link = &uctx_main;
makecontext(&uctx_func1, func1, 0);
getcontext(&uctx_func2);
uctx_func2.uc_stack.ss_sp = func2_stack;
uctx_func2.uc_stack.ss_size = sizeof(func2_stack);
uctx_func2.uc_link = &uctx_main;
makecontext(&uctx_func2, func2, 0);
swapcontext(&uctx_main, &uctx_func1);
swapcontext(&uctx_main, &uctx_func2);
swapcontext(&uctx_main, &uctx_func1);
swapcontext(&uctx_main, &uctx_func2);
printf("hello, main\n");
return 0;
}

Connecting stdout to stdin of the same process in Linux

I'm writing an app that (ab)uses an APL engine, libapl.so. The library contains a mechanism to allow me to capture results, but some stuff it dumps to stdout and stderr. So my question is, is there way a to capture stuff written to stdout rather than having it go to a screen, get piped to another process, or some such? Is there a way, for example, to connect stdout to stdin of the same process? I've tinkered with pipe2(), dup(2), and various bits of weirdness in GTK+/Glib, but I haven't hit the right incantation yet.
Did some more poking--at least one solution seems to be to create a fifo, open() it twice, once for reading, one for writing, and dup2() the writing fd to the stdout fd. This results in writes to stdout going through the fifo pipe where it can be read by the application. (Thanks for some inspiration by someone named Hasturkun, almost 7 years ago.)
Here's a bit of demo code:
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
int
main (int ac, char *av[])
{
char tname[64];
sprintf (tname, "/tmp/testpipe%d", (int)getpid ());
int rc = mkfifo (tname, 0666);
if (rc != 0) {
perror ("Creating fifo");
return 1;
}
int temp_in_fd = open (tname, O_NONBLOCK | O_RDONLY);
if (temp_in_fd < 0) {
perror ("Opening new input");
return 1;
}
int temp_out_fd = open (tname, O_NONBLOCK | O_WRONLY);
if (temp_out_fd < 0) {
perror ("Opening new output");
return 1;
}
FILE *temp_in = fdopen (temp_in_fd, "r");
if (!temp_in) {
perror ("Creating new input FILE");
return 1;
}
FILE *temp_out = fdopen (temp_out_fd, "w");
if (!temp_out) {
perror ("Creating new input FILE");
return 1;
}
dup2 (fileno (temp_out), STDOUT_FILENO);
printf("Woot!");
fflush(stdout);
#define BFR_SIZE 64
char bfr[BFR_SIZE];
ssize_t sz = fread (bfr, 1, BFR_SIZE, temp_in);
fprintf (stderr, "got %d bytes: \"%s\"\n", (int)sz, bfr);
fclose (temp_out);
fclose (temp_in);
unlink (tname);
return 0;
}

publishing trajectory_msgs/jointtrajectory msgs

When i set the position and velocities of the joints in the trajectory msgs i got an error: \
[state_publisher-2] process has died [pid 13362, exit code -11, cmd /home/rob/catkin_ws/devel/lib/r2d2/state_publisher __name:=state_publisher __log:=/home/rob/.ros/log/9980f352-cf74-11e6-8644-d4c9efe8bd37/state_publisher-2.log].
log file: /home/rob/.ros/log/9980f352-cf74-11e6-8644-d4c9efe8bd37/state_publisher-2*.log
My ros node to send geometry_msgs is:
#include <string>
#include <ros/ros.h>
#include <sensor_msgs/JointState.h>
#include <tf/transform_broadcaster.h>
#include <trajectory_msgs/JointTrajectory.h>
#include <vector>
int main(int argc, char** argv) {
ros::init(argc, argv, "state_publisher");
ros::NodeHandle n;
ros::Publisher joint_pub = n.advertise<trajectory_ms
gs::JointTrajectory>("set_joint_trajectory", 1);
ros::Rate loop_rate(30);
const double degree = M_PI/180;
// robot state
double tilt = 0, tinc = degree, swivel=0, angle=0, height=0, hinc=0.005;
// message declarations
trajectory_msgs::JointTrajectory joint_state;
std::vector<trajectory_msgs::JointTrajectoryPoint> points_n(3);
points_n[0].positions[0] = 1; points_n[0].velocities[0]=10;
while (ros::ok()) {
//update joint_state
joint_state.header.stamp = ros::Time::now();
joint_state.joint_names.resize(3);
joint_state.points.resize(3);
joint_state.joint_names[0] ="swivel";
joint_state.points[0] = points_n[0];
joint_state.joint_names[1] ="tilt";
joint_state.points[1] = points_n[1];
joint_state.joint_names[2] ="periscope";
joint_state.points[2] = points_n[2];
joint_pub.publish(joint_state);
// This will adjust as needed per iteration
loop_rate.sleep();
}
return 0;
}
Here when i donot set the position and velocity value it runs without error and when i run rostopic echo /set_joint_trajectory i can clearly see the outputs as all the parameters of points is 0. I also tried below program but it published nothing:
#include <string>
#include <ros/ros.h>
#include <sensor_msgs/JointState.h>
#include <tf/transform_broadcaster.h>
#include <trajectory_msgs/JointTrajectory.h>
#include <vector>
int main(int argc, char** argv) {
ros::init(argc, argv, "state_publisher");
ros::NodeHandle n;
ros::Publisher joint_pub = n.advertise<trajectory_msgs::JointTrajectory>("set_joint_trajectory", 1);
trajectory_msgs::JointTrajectory joint_state;
joint_state.header.stamp = ros::Time::now();
joint_state.header.frame_id = "camera_link";
joint_state.joint_names.resize(3);
joint_state.points.resize(3);
joint_state.joint_names[0] ="swivel";
joint_state.joint_names[1] ="tilt";
joint_state.joint_names[2] ="periscope";
size_t size = 2;
for(size_t i=0;i<=size;i++) {
trajectory_msgs::JointTrajectoryPoint points_n;
int j = i%3;
points_n.positions.push_back(j);
points_n.positions.push_back(j+1);
points_n.positions.push_back(j*2);
joint_state.points.push_back(points_n);
joint_state.points[i].time_from_start = ros::Duration(0.01);
}
joint_pub.publish(joint_state);
ros::spinOnce();
return 0;
}
You are accessing points_n[0].positions[0] and points_n[0].velocities[0] without allocating the memory for positions and velocities. Use
...
// message declarations
trajectory_msgs::JointTrajectory joint_state;
std::vector<trajectory_msgs::JointTrajectoryPoint> points_n(3);
points_n[0].positions.resize(1);
points_n[0].velocities.resize(1);
...
then set the values or use points_n[0].positions.push_back(...) instead. The same applies to points_n[1] and points_n[2].
In your second example it looks like your program terminates before anything is sent. Try to publish repeatedly in a while-loop with
while(ros::ok()){
...
ros::spinOnce();
}

objectmaker.exe in haarclassification

I am trying in vs2012 and opencv 2.4.11 to run the objectmaker.exe in my project file which is created by the code and successfully build in release but when i am trying to double click to open it there is a run time error i cant fix it any help please .. my code is :
#include <opencv/cv.h>
#include <opencv/cvaux.h>
#include <opencv/highgui.h>
#include "stdafx.h"
#include "opencv2/highgui/highgui.hpp"
// for filelisting
#include <stdio.h>
#include <io.h>
// for fileoutput
#include <string>
#include <fstream>
#include <sstream>
#include "dirent.h"
#include <sys/types.h>
using namespace std;
using namespace cv;
IplImage* image=0;
IplImage* image2=0;
//int start_roi=0;
int roi_x0=0;
int roi_y0=0;
int roi_x1=0;
int roi_y1=0;
int numOfRec=0;
int startDraw = 0;
char* window_name="<SPACE>add <ENTER>save and load next <ESC>exit";
string IntToString(int num)
{
ostringstream myStream; //creates an ostringstream object
myStream << num << flush;
/*
* outputs the number into the string stream and then flushes
* the buffer (makes sure the output is put into the stream)
*/
return(myStream.str()); //returns the string form of the stringstream object
};
void on_mouse(int event,int x,int y,int flag, void *param)
{
if(event==CV_EVENT_LBUTTONDOWN)
{
if(!startDraw)
{
roi_x0=x;
roi_y0=y;
startDraw = 1;
} else {
roi_x1=x;
roi_y1=y;
startDraw = 0;
}
}
if(event==CV_EVENT_MOUSEMOVE && startDraw)
{
//redraw ROI selection
image2=cvCloneImage(image);
cvRectangle(image2,cvPoint(roi_x0,roi_y0),cvPoint(x,y),
CV_RGB(255,0,255),1);
cvShowImage(window_name,image2);
cvReleaseImage(&image2);
}
}
int main(int argc, char** argv)
{
int iKey=0;
string strPrefix;
string strPostfix;
string input_directory;
string output_file;
if(argc != 3) {
fprintf(stderr, "%s output_info.txt raw/data/directory/\n", argv[0]);
return -1;
}
input_directory = argv[2];
output_file = argv[1];
/* Get a file listing of all files with in the input directory */
DIR *dir_p = opendir (input_directory.c_str());
struct dirent *dir_entry_p;
if(dir_p == NULL) {
fprintf(stderr, "Failed to open directory %s\n", input_directory.c_str());
return -1;
}
fprintf(stderr, "Object Marker: Input Directory: %s Output File: %s\n", input_directory.c_str(), output_file.c_str());
// init highgui
cvAddSearchPath(input_directory);
cvNamedWindow(window_name,1);
cvSetMouseCallback(window_name,on_mouse, NULL);
fprintf(stderr, "Opening directory...");
// init output of rectangles to the info file
ofstream output(output_file.c_str());
fprintf(stderr, "done.\n");
while((dir_entry_p = readdir(dir_p)) != NULL)
{
numOfRec=0;
if(strcmp(dir_entry_p->d_name, ""))
fprintf(stderr, "Examining file %s\n", dir_entry_p->d_name);
/* TODO: Assign postfix/prefix info */
strPostfix="";
strPrefix=input_directory;
strPrefix+=dir_entry_p->d_name;
//strPrefix+=bmp_file.name;
fprintf(stderr, "Loading image %s\n", strPrefix.c_str());
if((image=cvLoadImage(strPrefix.c_str(),1)) != 0)
{
// work on current image
do
{
cvShowImage(window_name,image);
// used cvWaitKey returns:
// <Enter>=13 save added rectangles and show next image
// <ESC>=27 exit program
// <Space>=32 add rectangle to current image
// any other key clears rectangle drawing only
iKey=cvWaitKey(0);
switch(iKey)
{
case 27:
cvReleaseImage(&image);
cvDestroyWindow(window_name);
return 0;
case 32:
numOfRec++;
printf(" %d. rect x=%d\ty=%d\tx2h=%d\ty2=%d\n",numOfRec,roi_x0,roi_y0,roi_x1,roi_y1);
//printf(" %d. rect x=%d\ty=%d\twidth=%d\theight=%d\n",numOfRec,roi_x1,roi_y1,roi_x0-roi_x1,roi_y0-roi_y1);
// currently two draw directions possible:
// from top left to bottom right or vice versa
if(roi_x0<roi_x1 && roi_y0<roi_y1)
{
printf(" %d. rect x=%d\ty=%d\twidth=%d\theight=%d\n",numOfRec,roi_x0,roi_y0,roi_x1-roi_x0,roi_y1-roi_y0);
// append rectangle coord to previous line content
strPostfix+=" "+IntToString(roi_x0)+" "+IntToString(roi_y0)+" "+IntToString(roi_x1-roi_x0)+" "+IntToString(roi_y1-roi_y0);
}
if(roi_x0>roi_x1 && roi_y0>roi_y1)
{
printf(" %d. rect x=%d\ty=%d\twidth=%d\theight=%d\n",numOfRec,roi_x1,roi_y1,roi_x0-roi_x1,roi_y0-roi_y1);
// append rectangle coord to previous line content
strPostfix+=" "+IntToString(roi_x1)+" "+IntToString(roi_y1)+" "+IntToString(roi_x0-roi_x1)+" "+IntToString(roi_y0-roi_y1);
}
break;
}
}
while(iKey!=13);
// save to info file as later used for HaarTraining:
// <rel_path>\bmp_file.name numOfRec x0 y0 width0 height0 x1 y1 width1 height1...
if(numOfRec>0 && iKey==13)
{
//append line
/* TODO: Store output information. */
output << strPrefix << " "<< numOfRec << strPostfix <<"\n";
}
cvReleaseImage(&image);
} else {
fprintf(stderr, "Failed to load image, %s\n", strPrefix.c_str());
}
}
output.close();
cvDestroyWindow(window_name);
closedir(dir_p);
return 0;
}

Resources