Why is if (fork() == 0) { getpid() } and a popen() process returning the same process id? - c++

I want to know why the two process id's match when the the getpid() in the fork() to my knowledge is supposed to be a different process than the one produced by popen().
I was informed that my code only works because of what I interpret might be a bug with Ubuntu based distro's such as Xubuntu, Lubuntu, and KDE neon, (which are the distro's I've tested so far). You can easily compile and test the code from here: https://github.com/time-killer-games/XTransientFor Ignore the x64 binary available at that link if you don't trust it. Arch, RedHat, etc. testers are especially welcome to give feedback if this happens to not work for them.
Here's a much more minimal approach to demonstrating the issue:
// USAGE: xprocesstest [command]
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/Xutil.h>
#include <unistd.h>
#include <thread>
#include <chrono>
#include <iostream>
#include <string>
using std::string;
static inline Window XGetActiveWindow(Display *display) {
unsigned long window;
unsigned char *prop;
Atom actual_type, filter_atom;
int actual_format, status;
unsigned long nitems, bytes_after;
int screen = XDefaultScreen(display);
window = RootWindow(display, screen);
filter_atom = XInternAtom(display, "_NET_ACTIVE_WINDOW", True);
status = XGetWindowProperty(display, window, filter_atom, 0, 1000, False, AnyPropertyType, &actual_type, &actual_format, &nitems, &bytes_after, &prop);
unsigned long long_property = prop[0] + (prop[1] << 8) + (prop[2] << 16) + (prop[3] << 24);
XFree(prop);
return (Window)long_property;
}
static inline pid_t XGetActiveProcessId(Display *display) {
unsigned long window = XGetActiveWindow(display);
unsigned char *prop;
Atom actual_type, filter_atom;
int actual_format, status;
unsigned long nitems, bytes_after;
filter_atom = XInternAtom(display, "_NET_WM_PID", True);
status = XGetWindowProperty(display, window, filter_atom, 0, 1000, False, AnyPropertyType, &actual_type, &actual_format, &nitems, &bytes_after, &prop);
unsigned long long_property = prop[0] + (prop[1] << 8) + (prop[2] << 16) + (prop[3] << 24);
XFree(prop);
return (pid_t)(long_property - 1);
}
int main(int argc, const char **argv) {
if (argc == 2) {
char *buffer = NULL;
size_t buffer_size = 0;
string str_buffer;
FILE *file = popen(argv[1], "r");
if (fork() == 0) {
Display *display = XOpenDisplay(NULL);
Window window;
unsigned i = 0;
while (i < 10) {
std::this_thread::sleep_for(std::chrono::milliseconds(200));
if (XGetActiveProcessId(display) == getpid()) {
window = XGetActiveWindow(display);
break;
}
i++;
}
if (window == XGetActiveWindow(display))
std::cout << "process id's match!" << std::endl;
else std::cout << "process id's don't match!" << std::endl;
XCloseDisplay(display);
exit(0);
}
while (getline(&buffer, &buffer_size, file) != -1)
str_buffer += buffer;
std::cout << str_buffer;
free(buffer);
pclose(file);
}
}
Compile with:
cd "${0%/*}"
g++ -c -std=c++17 "xprocesstest.cpp" -fPIC -m64
g++ "xprocesstest.o" -o "xprocesstest" -fPIC -lX11
Run with:
cd "${0%/*}"
./xprocesstest "kdialog --getopenfilename"
You can replace the command in the quotes with any executable which sets the _NET_WM_PID atom.

#thatotherguy explains the answer in his comment:
"Are you aware that due to your - 1 you're actually checking that the two processes have sequential pids? This is not surprising behavior on Linux. Differences between distros would be down to whether sh optimizes out the extra fork it uses to run the command"
static inline pid_t XGetActiveProcessId(Display *display) {
unsigned long window = XGetActiveWindow(display);
unsigned char *prop;
Atom actual_type, filter_atom;
int actual_format, status;
unsigned long nitems, bytes_after;
filter_atom = XInternAtom(display, "_NET_WM_PID", True);
status = XGetWindowProperty(display, window, filter_atom, 0, 1000, False, AnyPropertyType, &actual_type, &actual_format, &nitems, &bytes_after, &prop);
unsigned long long_property = prop[0] + (prop[1] << 8) + (prop[2] << 16) + (prop[3] << 24);
XFree(prop);
return (pid_t)(long_property - 1);
}
That - 1 in the process id return I initially added because I thought at the time it was returning the wrong process id, because I thought when I wrote that the fork() was supposed to have the same process id as the popen, which later on I discovered wasn't the case. I subtracted one, thus making two different otherwise correct process id's, incorrectly equal.
Here's the correct way to do what I intended to do, in my original code, which lead to me asking this question; I wanted to know how to detect if a fork and popen child processes stem from a common parent process (while removing the subtraction of one from the return of the GetActiveProcessId() function):
#include <proc/readproc.h>
#include <cstring>
static inline pid_t GetParentPidFromPid(pid_t pid) {
proc_t proc_info; pid_t ppid;
memset(&proc_info, 0, sizeof(proc_info));
PROCTAB *pt_ptr = openproc(PROC_FILLSTATUS | PROC_PID, &pid);
if(readproc(pt_ptr, &proc_info) != 0) {
ppid = proc_info.ppid;
string cmd = proc_info.cmd;
if (cmd == "sh")
ppid = GetParentPidFromPid(ppid);
} else ppid = 0;
closeproc(pt_ptr);
return ppid;
}
Using the above helper function, while replacing the while loop, in the original code, with this, allows me to do what I was after:
while (i < 10) {
std::this_thread::sleep_for(std::chrono::milliseconds(200));
if (GetParentPidFromPid(XGetActiveProcessId(display)) == GetParentPidFromPid(getpid()) ||
GetParentPidFromPid(GetParentPidFromPid(XGetActiveProcessId(display))) == GetParentPidFromPid(getppid())) {
window = XGetActiveWindow(display);
break;
}
i++;
}
As #thatotherguy also pointed out, some distros will return a different parent process because the sh cmd will use run directly. To solve this, I did an or check in the if statement for seeing whether the parent or "grandparent" process id's returned equal, while attempting to skip any parent processes with the sh cmd value.
The helper function needs the -lprocps linker flag and libprocps-dev package installed if you are on a Debian based system. Package name will be different on other distros.

Related

wait() hangs when CLONE_THREAD

I am tracing some processes and their children using ptrace. I am trying to print specific system call (using Seccomp filter that notifies ptrace, see this blogpost).
In most cases my code (see below) is working fine. However, when I am tracing a java program (from the default-jre package), the latter clones using the CLONE_THREAD flag. And for some reason, my tracer hangs (I believe) because I can't receive signals from the cloned process. I think the reason is that (according to this discussion) the child process in fact becomes a child of the original process' parent, instead of becoming the original process' child.
I reproduced this issue by using a simple program that simply calls clone() with flags and perform actions. When I used the when I use CLONE_THREAD | CLONE_SIGHAND | CLONE_VM flags (as clone() documentation specifies they should come together since Linux 2.6.0), at least I am able to trace everything correctly until one of the two thread finishes.
I would like to trace both thread independently. Is it possible?
More importantly, I need to trace a Java program, and I cannot change it. Here a strace of the Java program clone call:
[...]
4665 clone(child_stack=0x7fb166e95fb0, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, parent_tid=[4666], tls=0x7fb166e96700, child_tidptr=0x7fb166e969d0) = 4666
[...]
So Java seems to respect the rules. I wanted to experiment to understand: I ruled out any flags unrelated to thread (i.e., `CLONE_FS | CLONE_FILES | CLONE_SYSVSEM).
Here are the results of running my test program with different combination of flags (I know, I am really desperate):
CLONE_VM|CLONE_SIGHAND|CLONE_THREAD|CLONE_SETTLS: only gets trace from parent
CLONE_VM|CLONE_SIGHAND|CLONE_THREAD|CLONE_PARENT_SETTID: inconsistent; gets trace from both until the parent finishes
CLONE_VM|CLONE_SIGHAND|CLONE_THREAD|CLONE_CHILD_CLEARTID: inconsistent; gets trace from both until the child finishes
CLONE_VM|CLONE_SIGHAND|CLONE_THREAD|CLONE_SETTLS|CLONE_PARENT_SETTID: only gets trace from parent
CLONE_VM|CLONE_SIGHAND|CLONE_THREAD|CLONE_SETTLS|CLONE_CHILD_CLEARTID: only gets trace from parent
CLONE_VM|CLONE_SIGHAND|CLONE_THREAD|CLONE_PARENT_SETTID|CLONE_SETTLS: only gets trace from parent
CLONE_VM|CLONE_SIGHAND|CLONE_THREAD|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID: inconsistent; gets trace from both until the child finishes
CLONE_VM|CLONE_SIGHAND|CLONE_THREAD|CLONE_CHILD_CLEARTID|CLONE_SETTLS: only gets trace from parent
CLONE_VM|CLONE_SIGHAND|CLONE_THREAD|CLONE_CHILD_CLEARTID|CLONE_PARENT_SETTID: inconsistent; gets trace from both until the child finishes
CLONE_VM|CLONE_SIGHAND|CLONE_THREAD|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID:
only gets trace from parent
So at least I get the same behaviour from my program and the Java program: it does not work.
How can I make it work? For instance, how does strace successfully traces any kind of clone? I tried to dig into its code but I can't find how they are doing it.
Any help might appreciated!
Best regards,
The tracer code (compile with g++ tracer.cpp -o tracer -g -lseccomp -lexplain):
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <stddef.h>
#include <sys/ptrace.h>
#include <sys/reg.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <sys/user.h>
#include <sys/prctl.h>
#include <fcntl.h>
#include <linux/limits.h>
#include <linux/filter.h>
#include <linux/seccomp.h>
#include <linux/unistd.h>
#include <libexplain/waitpid.h>
#include <tuple>
#include <vector>
#define DEFAULT_SIZE 1000
#define MAX_SIZE 1000
int process_signals();
int inspect(pid_t);
void read_string_into_buff(const pid_t, unsigned long long, char *, unsigned int);
int main(int argc, char **argv){
pid_t pid;
int status;
if (argc < 2) {
fprintf(stderr, "Usage: %s <prog> <arg1> ... <argN>\n", argv[0]);
return 1;
}
if ((pid = fork()) == 0) {
/* If execve syscall, trace */
struct sock_filter filter[] = {
BPF_STMT(BPF_LD+BPF_W+BPF_ABS, offsetof(struct seccomp_data, nr)),
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_getpid, 0, 1),
BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_TRACE),
BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),
};
struct sock_fprog prog = {
.len = (unsigned short) (sizeof(filter)/sizeof(filter[0])),
.filter = filter,
};
ptrace(PTRACE_TRACEME, 0, 0, 0);
if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) == -1) {
perror("prctl(PR_SET_NO_NEW_PRIVS)");
return 1;
}
if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog) == -1) {
perror("when setting seccomp filter");
return 1;
}
kill(getpid(), SIGSTOP);
return execvp(argv[1], argv + 1);
} else {
waitpid(pid, &status, 0);
ptrace(PTRACE_SETOPTIONS, pid, 0, PTRACE_O_TRACESECCOMP | PTRACE_O_TRACEFORK | PTRACE_O_TRACECLONE | PTRACE_O_TRACEVFORK );
ptrace(PTRACE_CONT, pid, 0, 0);
process_signals();
return 0;
}
}
int process_signals(){
int status;
while (1){
pid_t child_pid;
// When child status changes
if ((child_pid = waitpid(-1, &status, 0)) < 0){
fprintf(stderr, "%s\n", explain_waitpid(child_pid, &status, 0));
exit(EXIT_FAILURE);
}
//printf("Sigtrap received\n");
// Checking if it is thanks to seccomp
if (status >> 8 == (SIGTRAP | (PTRACE_EVENT_SECCOMP << 8))){
// Perform argument inspection with ptrace
int syscall = inspect(child_pid);
}
// Resume no matter what
ptrace(PTRACE_CONT, child_pid, 0, 0);
}
}
int inspect(pid_t pid){
printf("From PID: %d\n", pid);
struct user_regs_struct regs;
ptrace(PTRACE_GETREGS, pid, 0, &regs);
// Get syscall number
int syscall = regs.orig_rax;
printf("------\nCaught syscall: %d\n", syscall);
if (syscall == __NR_getpid){
printf("Getpid detected\n");
}
return syscall;
}
void read_string_into_buff(const pid_t pid, unsigned long long addr, char * buff, unsigned int max_len){
/* Are we aligned on the "start" front? */
unsigned int offset=((unsigned long)addr)%sizeof(long);
addr-=offset;
unsigned int i=0;
int done=0;
int word_offset=0;
while( !done ) {
unsigned long word=ptrace( PTRACE_PEEKDATA, pid, addr+(word_offset++)*sizeof(long), 0 );
// While loop to stop at the first '\0' char indicating end of string
while( !done && offset<sizeof(long) && i<max_len ) {
buff[i]=((char *)&word)[offset]; /* Endianity neutral copy */
done=buff[i]=='\0';
++i;
++offset;
}
offset=0;
done=done || i>=max_len;
}
}
The sample program (compile with gcc sample.c -o sample):
#define _GNU_SOURCE
#include <stdio.h>
#include <sched.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
#include <signal.h>
#define FLAGS CLONE_VM|CLONE_SIGHAND|CLONE_THREAD|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID
int fn(void *arg)
{
printf("\nINFO: This code is running under child process.\n");
int i = 0;
int n = atoi(arg);
for ( i = 1 ; i <= 10 ; i++ )
printf("[%d] %d * %d = %d\n", getpid(), n, i, (n*i));
printf("\n");
return 0;
}
void main(int argc, char *argv[])
{
printf("[%d] Hello, World!\n", getpid());
void *pchild_stack = malloc(1024 * 1024);
if ( pchild_stack == NULL ) {
printf("ERROR: Unable to allocate memory.\n");
exit(EXIT_FAILURE);
}
int pid = clone(fn, pchild_stack + (1024 * 1024), FLAGS, argv[1]);
if ( pid < 0 ) {
printf("ERROR: Unable to create the child process.\n");
exit(EXIT_FAILURE);
}
fn(argv[1]);
wait(NULL);
free(pchild_stack);
printf("INFO: Child process terminated.\n");
}
You can test what you want by running ./tracer ./sample. You can also test the original test case ./tracer java and observe that both the tracer and java hangs.
ANSWER:
As pointed it out in the comment, I had issues in that example that were preventing me from handling signals from the child.
In my original code (not listed here because too complex), I was only attaching ptrace AFTER the processes started... and I was only attaching to PID listed by pstree. My mistake was that I omitted the threads (and java is one program that does create threads), explaining why I had issue tracing java only.
I modified the code to attach to all the children process and thread (ps -L -g <Main_PID> -o tid=) and everything works again.
Your sample program has a bug: it may free the second thread’s stack before that thread exits, causing a SEGV. And your tracer just doesn’t handle signals well.
If the traced program gets a signal, your tracer intercepts it, not passing it down to the program. When it continues the program, it continues from the very same operation that caused SEGV, so it gets SEGV again. Ad infinitum. Both the tracer and the tracee appear to hang but in fact, they are in an infinite loop.
Rewriting the continuation like the following seems to work:
if (status >> 8 == (SIGTRAP | (PTRACE_EVENT_SECCOMP << 8))){
// Perform argument inspection with ptrace
int syscall = inspect(child_pid);
ptrace(PTRACE_CONT, child_pid, 0, 0);
} else if (WIFSTOPPED(status)) {
ptrace(PTRACE_CONT, child_pid, 0, WSTOPSIG(status));
} else {
ptrace(PTRACE_CONT, child_pid, 0, 0);
}
Not sure of Java but it seems to get SEGVs in regular operation...

Running an executable from a C++ program in the same process

Is that possible? I'd like an easy access to the executable's memory to edit it. Alternately, when I'm not the administrator, is it possible to edit the executable's memory from another process? I've tried the ptrace library and it fails if I'm not the administrator. I'm on Linux
I'm not entirely sure what you are asking, but this is possible with shared memory.
See here: http://www.kernel.org/doc/man-pages/online/pages/man7/shm_overview.7.html
This is what a debugger does. You could look at the code of an open source debugger, e.g. gdb, to see how it works.
The answer:
Yes - it works: you don't have to be administrator / root, but of course you need the rights to access the process' memory, i.e. same user.
No - it is not easy
The possibility to write to /proc/pid/mem was added some time ago to the Linux kernel. Therefore it depends on the kernel you are using. The small programs were checked with kernel 3.2 where this works and 2.6.32 where it fails.
The solution consists of two programs:
A 'server' which is started, allocates some memory, writes some pattern into this memory and outputs every three seconds the memory contents which is placed after the pattern is printed.
A 'client' which connects via the /proc/pid/maps and /proc/pid/mem to the server, searches for the pattern and writes some other string into the server's memory.
The implementation uses heap - but as long as the permissions allow - it is also possible to change other portions of the other process' memory.
This is implemented in C, because it is very 'low level' - but it should work in C++. It is a proof of concept - no production code - e.g. there are some error checks missing and it has some fixed size buffers.
memholder.c
/*
* Alloc memory - write in some pattern and print out the some bytes
* after the pattern.
*
* Compile: gcc -Wall -Werror memholder.c -o memholder.o
*/
#include <sys/types.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
int main() {
char * m = (char*) malloc(2048);
memset(m, '\xAA', 1024);
strcpy(m + 1024, "Some local data.");
printf("PID: %d\n", getpid());
while(1) {
printf("%s\n", m + 1024);
sleep(3);
}
return 0;
}
memwriter.c
/*
* Searches for a pattern in the given PIDs memory
* and changes some bytes after them.
*
* Compile: gcc -Wall -std=c99 -Werror memwriter.c -o memwriter
*/
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/ptrace.h>
#include <sys/wait.h>
int open_proc_file(pid_t other_pid, char const * const sn,
int flags) {
char fname[1024];
snprintf(fname, 1023, "/proc/%d/%s", other_pid, sn);
// Open file for reading and writing
int const fd = open(fname, flags );
if(fd==-1) {
perror("Open file");
exit(1);
}
return fd;
}
void get_heap(int fd_maps, size_t * heap_start, size_t * heap_end) {
char buf[65536];
ssize_t const r = read(fd_maps, buf, 65535);
if(r==-1) {
perror("Reading maps file");
exit(1);
}
buf[r] = '\0';
char * const heap = strstr(buf, "[heap]");
if(heap==NULL) {
printf("[heap] not found in maps file");
exit(1);
}
// Look backward to the latest newline
char const * hl_start;
for(hl_start = heap; hl_start > buf && *hl_start != '\n';
--hl_start) {}
// skip \n
++hl_start;
// Convert to beginnig and end address
char * lhe;
*heap_start = strtol(hl_start, &lhe, 16);
++lhe;
*heap_end = strtol(lhe, &lhe, 16);
}
int main(int argc, char *argv[]) {
if(argc!=2) {
printf("Usage: memwriter <pid>\n");
return 1;
}
pid_t const other_pid = atoi(argv[1]);
int fd_mem = open_proc_file(other_pid, "mem", O_RDWR);
int fd_maps = open_proc_file(other_pid, "maps", O_RDONLY);
size_t other_mem_start;
size_t other_mem_end;
get_heap(fd_maps, &other_mem_start, &other_mem_end);
ptrace(PTRACE_ATTACH, other_pid, NULL, NULL);
waitpid(other_pid, NULL, 0);
if( lseek(fd_mem, other_mem_start, SEEK_SET) == -1 ) {
perror("lseek");
return 1;
}
char buf[512];
do {
ssize_t const r = read(fd_mem, buf, 512);
if(r!=512) {
perror("read?");
break;
}
// Check for pattern
int pat_found = 1;
for(int i = 0; i < 512; ++i) {
if( buf[i] != '\xAA' )
pat_found = 0;
break;
}
if( ! pat_found ) continue;
// Write about one k of strings
char const * const wbuf = "REMOTE DATA - ";
for(int i = 0; i < 70; ++i) {
ssize_t const w = write(fd_mem, wbuf, strlen(wbuf));
if( w == -1) {
perror("Write");
return 1;
}
}
// Append a \0
write(fd_mem, "\0", 1);
break;
} while(1);
ptrace(PTRACE_DETACH, other_pid, NULL, NULL);
close(fd_mem);
close(fd_maps);
return 0;
}
Example output
$ ./memholder
PID: 2621
Some local data.
Some local data.
MOTE DATA - REMOTE DA...
Other interpretation
There is also another interpretation of your question (when reading the headline and not the question), that you want to replace the 'executable' from one process with another one. That can be easily handled by exec() (and friends):
From man exec:
The exec() family of functions replaces the current process image with a new process image.
In Windows, the methods used for this are named ReadProcessMemory / WriteProcessMemory, you will, however, need administrative rights for this. The same is for linux, as I've said in my comment, no sane system would allow user process to modify non-owned memory.
For linux, the only function is ptrace. You will need to be administrator.
http://cboard.cprogramming.com/cplusplus-programming/92093-readprocessmemory-writeprocessmemory-linux-equivalent.html contains more detailed discussion.
Can you imagine the consequences of allowing process to modify other process memory, without being administrator?

Windows Semaphore and QSystemSemaphore

I have a problem with semaphores in Windows between two application. An application waits for release signal(Qt) and the other application sends release signal(MSVC2008). But it dose not work.
I tested Qt-Qt and MSVC2008-MSVC2008 modes and they was succeed. But when I try Qt-MSVC2008 mode it fails.
// MSVC2008:
#include <windows.h>
#include <stdio.h>
int main()
{
const WCHAR semName[] = L"TestSem";
PHANDLE sem = (HANDLE *) CreateSemaphore (NULL, 0, 1, semName);
if (sem == NULL)
{
sem = (HANDLE *)OpenSemaphore (SEMAPHORE_ALL_ACCESS, 0, semName);
}
if (sem == NULL)
{
printf("OPEN/CREATE ERROR\n");
return 0;
}
BOOL r = ReleaseSemaphore(sem, 1 ,NULL);
if (r)
printf("OK\n");
else
printf("RELEASE ERROR\n");
CloseHandle (sem);
return 0;
}
and
// Qt 4.8.0 :
#include <QSystemSemaphore>
#include <QCoreApplication>
#include <iostream>
int main()
{
QSystemSemaphore *sem_read = new QSystemSemaphore("TestSem");
std::cout << "Wait for signal: " << std::endl;
while (1)
{
sem_read->acquire();
std::cout << "Hi" << std::endl;
}
return 0;
}
I expect when Qt-app is running, after executing MSVC2008-app, it prints one "Hi" in the screen. But it dose not. What is the problem?!
Note: I'm using Windows 7 and MinGW compiler for Qt
Looking at the Qt sources (4.7.3) I see at corelib/kernel/qsystemsemaphore_p.h:79 that the semaphore name generated by Qt is prefixed by qipc_systemsem_.
[UPDATE] The sha1 hash of "TestSem" is also appended, so the resulting Qt semaphore name is qipc_systemsem_TestSem3ec37c26f212774998f34a4e6722cac152ad17fa
Confirmed working.
To generate the semaphore name:
QString prefix = "qipc_systemsem_";
QString key = "TestSem";
QString result = prefix;
QString part1 = key;
part1.replace(QRegExp(QLatin1String("[^A-Za-z]")), QString());
result.append(part1);
QByteArray hex = QCryptographicHash::hash(key.toUtf8(), QCryptographicHash::Sha1).toHex();
result.append(QLatin1String(hex));
qDebug() << result;
2 things I'd look into:
QSystemSemaphore requires an initial values and initiated with 0 if it is not given. Maybe start it with 1?
this is a system semaphore, could it be that your first test did not release it? try to change the name maybe.

C++ windows threading and mutex issue

I am a bit rusty with threaded programs especially in windows.
I have created a simple mex file in Matlab that is meant to read a number of files with each file being read in its own thread.
The file doesnt do anything really useful but is a precursor to a more complicated version that will use all of the functionality ive put into this file.
Here is the code:
#include <windows.h>
#include "mex.h"
#include <fstream>
typedef unsigned char uchar;
typedef unsigned int uint;
using namespace std;
int N;
int nThreads;
const int BLOCKSIZE = 1024;
char * buffer;
char * out;
HANDLE hIOMutex;
DWORD WINAPI runThread(LPVOID argPos) {
int pos = *(reinterpret_cast<int*>(argPos));
DWORD dwWaitResult = WaitForSingleObject( hIOMutex, INFINITE );
if (dwWaitResult == WAIT_OBJECT_0){
char buf[20];
sprintf(buf, "test%i.dat", pos);
ifstream ifs(buf, ios::binary);
if (!ifs.fail()) {
mexPrintf("Running thread:%i\n", pos);
for (int i=0; i<N/BLOCKSIZE;i++) {
if (ifs.eof()){
mexPrintf("File %s exited at i=%i\n", buf, (i-1)*BLOCKSIZE);
break;
}
ifs.read(&buffer[pos*BLOCKSIZE], BLOCKSIZE);
}
}
else {
mexPrintf("Could not open file %s\n", buf);
}
ifs.close();
ReleaseMutex( hIOMutex);
}
else
mexPrintf("The Mutex failed in thread:%i \n", pos);
return TRUE;
}
// 0 - N is data size
// 1 - nThreads is number of threads
// 2 - this is the output array
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray*prhs[] ) {
N = mxGetScalar(prhs[0]);
nThreads = mxGetScalar(prhs[1]);
out = (char*)mxGetData(prhs[2]);
buffer = (char*)malloc(BLOCKSIZE*nThreads);
hIOMutex= CreateMutex(NULL, FALSE, NULL);
HANDLE *hArr = (HANDLE*)malloc(sizeof(HANDLE)*nThreads);
int *tInd = (int*)malloc(sizeof(int)*nThreads);
for (int i=0;i<nThreads;i++){
tInd[i]=i;
hArr[i] = CreateThread( NULL, 0, runThread, &tInd[i], 0, NULL);
if (!hArr[i]) {
mexPrintf("Failed to start thread:%i\n", i);
break;
}
}
WaitForMultipleObjects( nThreads, hArr, TRUE, INFINITE);
for (int i=0;i<nThreads;i++)
CloseHandle(hArr[i]);
CloseHandle(hIOMutex);
mexEvalString("drawnow");
mexPrintf("Finished all threads.\n");
free(hArr);
free(tInd);
free(buffer);
I compile it like this in Matlab:
mex readFile.cpp
And then run it like this:
out = zeros(1024*1024,1,'uint8');
readFile(1024*1024,nFiles,out);
The problem is that when I set nFiles to be less than or equal to 64 everything works as expected and I get the following output:
Running thread:0
.
.
.
Running thread:62
Running thread:63
Finished all threads.
However when I set nFiles to 65 or larger I get:
Running thread:0
Running thread:1
Running thread:2
Running thread:3
The Mutex failed in thread:59
The Mutex failed in thread:60
The Mutex failed in thread:61
.
.
.
(up to nFiles-1)
Finished all threads.
I have also tested it without threading and it works fine.
I cannot see what Im doing wrong or why the cutoff to using the mutex would be so arbitrary so I am assuming there is something I am not taking into account.
Can anyone see where I have a blatant mistake relating to the error Im seeing?
In the documentation for WaitForMultipleObjects, "The maximum number of object handles is MAXIMUM_WAIT_OBJECTS.", which is 64 on most systems.
This is also (almost) a duplicate of this thread. The summary is really just that yes, the limit is 64, and also to use the information in the remarks section of WaitForMultipleObjects to build up a tree of threads to wait on.

How to identify top-level X11 windows using xlib?

I'm trying to get a list of all top level desktop windows in an X11 session. Basically, I want to get a list of all windows that are shown in the window managers application-switching UI (commonly opened when the user presses ALT+TAB).
I've never done any X11 programming before, but so far I've managed to enumerate through the entire window list, with code that looks something like this:
void CSoftwareInfoLinux::enumerateWindows(Display *display, Window rootWindow)
{
Window parent;
Window *children;
Window *child;
quint32 nNumChildren;
XTextProperty wmName;
XTextProperty wmCommand;
int status = XGetWMName(display, rootWindow, &wmName);
if (status && wmName.value && wmName.nitems)
{
int i;
char **list;
status = XmbTextPropertyToTextList(display, &wmName, &list, &i);
if (status >= Success && i && *list)
{
qDebug() << "Found window with name:" << (char*) *list;
}
status = XGetCommand(display, rootWindow, &list, &i);
if (status >= Success && i && *list)
{
qDebug() << "... and Command:" << i << (char*) *list;
}
Window tf;
status = XGetTransientForHint(display, rootWindow, &tf);
if (status >= Success && tf)
{
qDebug() << "TF set!";
}
XWMHints *pHints = XGetWMHints(display, rootWindow);
if (pHints)
{
qDebug() << "Flags:" << pHints->flags
<< "Window group:" << pHints->window_group;
}
}
status = XQueryTree(display, rootWindow, &rootWindow, &parent, &children, &nNumChildren);
if (status == 0)
{
// Could not query window tree further, aborting
return;
}
if (nNumChildren == 0)
{
// No more children found. Aborting
return;
}
for (int i = 0; i < nNumChildren; i++)
{
enumerateWindows(display, children[i]);
}
XFree((char*) children);
}
enumerateWindows() is called initially with the root window.
This works, in so far as it prints out information about hundreds of windows - what I need, is to work out which property I can interrogate to determine if a given Window is a top-level Desktop application window (not sure what the official terminology is), or not.
Can anyone shed some light on this? All the reference documentation I've found for X11 programming has been terribly dry and hard to understand. Perhaps someone could point be to a better resource?
I have a solution!
Well, sort of.
If your window manager uses the extended window manager hints (EWMH), you can query the root window using the "_NET_CLIENT_LIST" atom. This returna list of client windows the window manager is managing. For more information, see here.
However, there are some issues with this. For a start, the window manager in use must support the EWMH. KDE and GNOME do, and I'm sure some others do as well. However, I'm sure there are many that don't. Also, I've noticed a few issues with KDE. Basically, some non-KDE applications don't get included in the list. For example, if you run xcalc under KDE it won't show up in this list.
If anyone can provide any improvements on this method, I'd be glad to hear them. For reference, the code I'm using is listed below:
Atom a = XInternAtom(m_pDisplay, "_NET_CLIENT_LIST" , true);
Atom actualType;
int format;
unsigned long numItems, bytesAfter;
unsigned char *data =0;
int status = XGetWindowProperty(m_pDisplay,
rootWindow,
a,
0L,
(~0L),
false,
AnyPropertyType,
&actualType,
&format,
&numItems,
&bytesAfter,
&data);
if (status >= Success && numItems)
{
// success - we have data: Format should always be 32:
Q_ASSERT(format == 32);
// cast to proper format, and iterate through values:
quint32 *array = (quint32*) data;
for (quint32 k = 0; k < numItems; k++)
{
// get window Id:
Window w = (Window) array[k];
qDebug() << "Scanned client window:" << w;
}
XFree(data);
}
To expand on the previous solution, if you want to then get the window names:
// get window Id:
Window w = (Window) array[k];
char* name = '\0';
status = XFetchName(display, w, &name);
if (status >= Success)
{
if (name == NULL)
printf("Found: %ul NULL\n", w);
else
printf("Found: %ul %s\n", w, name);
}
XFree(name);
If you don't have to use Xlib, using GDK's gdk_screen_get_window_stack() and gdk_window_get_window_type() may help you out for your needs.