Why does my program work fine by running it directly but not as a service? Linux C - c

Goodday guys,
I am trying to build and run program in linux (raspberry) as a service.
It is a sample application that uses the Cerence SDK C API that implements a wake-up-word (WUW) plus command utterance recognition.
I can execute it by ./name.exe or using the Makefile commands.
The problem is that when I execute the program by console it works fine, without any problem.
When I try to execute it as a service (using both systemd or crontab and also rc.local), an error occours.
This is the function that gives me error:
printf("Selecting audio configuration %s\n", audioScenarioName);
rc = nuance_audio_IAudioManager_activateScenario(audioMgr, audioScenarioName);
if (NUANCE_COMMON_OK != rc) {
printf("Audio scenario activation failed: %d\n", rc); <-- returns 1 (error, impossible to activate scenario)
return rc;
}
ActivateScenario it's a function that simply selects the correct mic (audioScenarioName) following a JSON file and the audio manager (audioMgr).
Unfortunately this function returns 1 if something goes wrong, closes the program and nothing else.
This is the JSON:
"type": "AudioInput",
"name": "mic_input",
"adapter_type": "CUSTOM_AUDIO",
"adapter_params": {
"device_name": "default"
},
"audio_format": { "uses": "16khz_1ch" }
The service should be running as root permissions (default).
I also tried by setting the whole folder as chmod -R 777 as a test, but same problem.
This is my service:
[Unit]
Description=My Service
[Service]
Type=simple
ExecStart=+/home/pi/.../nameexec
Restart=on-failure
RestartSec=5
KillMode=process
[Install]
WantedBy=multi-user.target
I've also set the absolute path of its lib directory that it needs into the ld.so.conf file.
The only libraries I put in it are the .so ones, but not .h.
I am now trying to understand what might be different about starting the same executable but in different ways.
Could it be a permissions issue? Or is it not detecting the microphone? Any library out of place?
I really don't know why it works with the classic command and not as a service.
Can someone please help me with this?
Thank you in advance!

I succeeded!
The problem was the microphone being used.
Using Raspbian ver. Desktop, I set the mic from the bottom right part of the taskbar and changed the defaults in/out.
But these settings seem to be not system-wide and not used by the services in background (even though the "User=" is set to "pi").
So I had to change alsa.conf file:
sudo nano /usr/share/alsa/alsa.conf
Then find and edit these lines:
defaults.ctl.card cardnumber
defaults.pcm.card cardnumber
You can find the card number by running arecord -l.

Related

How do I check if my executable is running for a service or for a normal program?

I'm developing a win service in using mingw I've been trying for hours
I looked for examples on the internet I used ChatGPT
and nothing it returned works and the few examples I found
had nothing to do with what I wanted
I hope there is some way to do this the
idea and before i create the SERVICE_TABLE_ENTRY i can check if my executable was started
for a windows service,
if yes i create the
SERVICE_TABLE_ENTRY if I don't do anything else.
If your program supports multiple modes then I would suggest using a command line parameter like /service for the service registration.
Alternatively you could check if your process token contains S-1-5-6 (SECURITY_SERVICE_RID) but I'm not sure which Windows version that was introduced.
If you want to check if it's running you should check if the service is running. Check under services by running services.msc and looking for the service you registered.
Some time ago I wrote a simple library to make your program a service (on Windows) or daemon (on *nix):
https://sourceforge.net/projects/daemonservice/
Maybe you can check the source on how it was done there...
I saw a simple way to check this just create SERVICE_TABLE_ENTRY and use StartServiceCtrlDispatcher if it returns an error probably the executable was started like a normal program.
SERVICE_TABLE_ENTRY _dispatcher_entry_table[] =
{
{"", (LPSERVICE_MAIN_FUNCTION)serviceMain},
{NULL, NULL}
};
if (!StartServiceCtrlDispatcher(_dispatcher_entry_table))
{
DWORD __error_code = GetLastError();
if (__error_code == ERROR_FAILED_SERVICE_CONTROLLER_CONNECT)
{
//It's probably a normal program
}
else
{
//handle the errors
}
}

SWUpdate on RPi4 via yocto - error parsing configuration file

After booting SWUpdate yocto-generated image for the first time, executing swupdate results in error message:
Error parsing configuration file: 'globals' section missing, exiting.
I tried to strictly follow SWUpdate's documentation, but it gets short when it comes to yocto integration. I'm using meta-swupdate, meta-swupdate-boards, and meta-openembedded layers together with poky example repository all at Kirkstone tag, building via bitbake update-image and having modyfied local.conf as:
MACHINE ??= "raspberrypi4-64"
ENABLE_UART = "1"
RPI_USE_U_BOOT = "1"
IMAGE_FSTYPES = "wic ext4.gz"
PREFERRED_PROVIDER_u-boot-fw-utils = "libubootenv"
IMAGE_INSTALL:append = " swupdate"
Is there anything else I need to modify to generate the configuration file and be able to run SWUpdate binary properly?
Side question: In the documentation, it's recommended to append swupdate-www to achieve a better web server. However, if I append it, there is no swupdate-www binary inside the `/usr/bin' directory.
As with other recipes folders the recipes-support/swupdate/swupdate/raspberrypi4-64 folder was missing inside the meta-swupdate-boards layer. Therefore, an empty config file was always generated. After adding this folder and all related files, strongly inspired by raspberrypi3 folder, the error was gone and swupdate -h provided the expected output.
There was also one new error during build process thrown by yocto. It was related to missing systemd requirement and was solved by adding:
DISTRO_FEATURES_append = " systemd"
to local.conf

C program exits giving error ORA-12162: TNS:net service name is incorrectly specified

I am working on a remote red-hat server and there I'm developing a c application to insert data in to a remote oracle database. So first i installed the OCI instant client rpm on the server and tried to compile a sample program. after certain linkages I could compile it. But then when I am going to run it. It exits giving an error saying
ORA-12162: TNS:net service name is incorrectly specified
The sample code I used is from the blog (refer to this code in case you need to clarify the things.where I’m quoting only few pieces to this post) René Nyffenegger's collection of things on the web
René Nyffenegger on Oracle
(refer to this code in case you need to clarify the things.where I’m quoting only few pieces to this post)
In the code I added some prints to check for the error And it seems like It gets stuck in the OCIServerAttach() function r gives a printed walue of -1
r=OCIServerAttach(srv, err, dbname, strlen(dbname), (ub4) OCI_DEFAULT);
printf("r value %d",r);
if (r != OCI_SUCCESS) {
checkerr(err, r);
goto clean_up;
}
Another point is that in the compilation process it gives a warning saying that a certain libry is not include. but the exicutable file is created. Here is the massage I get in the compilation process.
[laksithe#loancust ~]$ gcc -L$ORACLE_HOME/lib/ -L$ORACLE_HOME/rdbms/lib/ -o oci_test oci_test.o -L/usr/lib/oracle/12.1/client64/lib -lclntsh `cat $ORACLE_HOME/lib/sysliblist`
cat: /lib/sysliblist: No such file or directory
Going through the web I found that by creating a tnsnames.ora file with the connection details I could solve the problem. But even It didn't work for me. Here is the link for that blog blog
It has been a week since this error and I cold'nt solve it. could someone please help me.
connection string format I used is abc.ghi.com:1521/JKLMN
My recommendation is to bypass tnsnames completely. Oracle has always allowed you to put in the direct connection details, but EZConnect makes that even easier.
When you format your connection string, instead of listing the TNS name, use the actual connection properties in the following format:
servername:port/service name
For Example
MyOracle.MyCompany.Com:1521/SalesReporting
Your connection string might also require direct=true, but I'm honestly not sure.
I like the idea of tnsnames, but it's a double edged sword. When it works, it's great. When it doesn't, you want to throw something. With EZConnect, it always works.
By the way, if you don't know the properties of the three items above, find a machine that connect via tnsnames and:
tnsping <your TNS-named database>

Can't Find "Syslog.conf" in linux kernal 2.6.37.6 created with BuysBox v1.19.3

I created a tiny OS for my controller with Linux kernel 2.6.37.6 with the help of BusyBox and tool chain. I am writing a logging module(C program) in it and i want customized logs(customized path for different logs) like in /log/.
I have syslogd in my machine and /etc/syslog.conf supposed to present in my machine but it's not it the place. I created new syslog.conf under /etc but still i can't find my logs in desired place.
But if i run command syslogd -O /log/Controller.log all logs started to redirect to this (specified file). So i want to know where is the configuration file for this syslogd i can't find the configuration file for it.
Is there any way that i can write a module(program) for LOGS without requiring syslog.conf and yes of course traditional printf way. Problem is that for customized paths for log we need to give keyname LOG_LOCAL1 in openlog() as a argument but it's not working
I followed procedure from this examples http://www.codealias.info/technotes/syslog_simple_example
If you are using Busybox's syslogd then there is no support of syslog.conf,all logs are written to /var/log/messages by default.
You can modify code of syslogd in busybox which is located in busybox/sysklogd/syslogd.c for your desire behaviour
You can change code of syslogd like this
static const struct init_globals init_data = {
.logFile = {
.path = "your desire path",
.fd = -1,
},

How to solve "ptrace operation not permitted" when trying to attach GDB to a process?

I'm trying to attach a program with gdb but it returns:
Attaching to process 29139
Could not attach to process. If your uid matches the uid of the target
process, check the setting of /proc/sys/kernel/yama/ptrace_scope, or try
again as the root user. For more details, see /etc/sysctl.d/10-ptrace.conf
ptrace: Operation not permitted.
gdb-debugger returns "Failed to attach to process, please check privileges and try again."
strace returns "attach: ptrace(PTRACE_ATTACH, ...): Operation not permitted"
I changed "kernel.yama.ptrace_scope" 1 to 0 and /proc/sys/kernel/yama/ptrace_scope 1 to 0 and tried set environment LD_PRELOAD=./ptrace.so with this:
#include <stdio.h>
int ptrace(int i, int j, int k, int l) {
printf(" ptrace(%i, %i, %i, %i), returning -1\n", i, j, k, l);
return 0;
}
But it still returns the same error. How can I attach it to debuggers?
If you are using Docker, you will probably need these options:
docker run --cap-add=SYS_PTRACE --security-opt seccomp=unconfined
If you are using Podman, you will probably need its --cap-add option too:
podman run --cap-add=SYS_PTRACE
This is due to kernel hardening in Linux; you can disable this behavior by echo 0 > /proc/sys/kernel/yama/ptrace_scope or by modifying it in /etc/sysctl.d/10-ptrace.conf
See also this article about it in Fedora 22 (with links to the documentation) and this comment thread about Ubuntu and .
I would like to add that I needed --security-opt apparmor=unconfined along with the options that #wisbucky mentioned. This was on Ubuntu 18.04 (both Docker client and host). Therefore, the full invocation for enabling gdb debugging within a container is:
docker run --cap-add=SYS_PTRACE --security-opt seccomp=unconfined --security-opt apparmor=unconfined
Just want to emphasize a related answer. Let's say that you're root and you've done:
strace -p 700
and get:
strace: attach: ptrace(PTRACE_SEIZE, 700): Operation not permitted
Check:
grep TracerPid /proc/700/status
If you see something like TracerPid: 12, i.e. not 0, that's the PID of the program that is already using the ptrace system call. Both gdb and strace use it, and there can only be one active at a time.
Not really addressing the above use-case but I had this problem:
Problem: It happened that I started my program with sudo, so when launching gdb it was giving me ptrace: Operation not permitted.
Solution: sudo gdb ...
As most of us land here for Docker issues I'll add the Kubernetes answer as it might come in handy for someone...
You must add the SYS_PTRACE capability in your pod's security context
at spec.containers.securityContext:
securityContext:
capabilities:
add: [ "SYS_PTRACE" ]
There are 2 securityContext keys at 2 different places. If it tells you that the key is not recognized than you missplaced it. Try the other one.
You probably need to have a root user too as default. So in the other security context (spec.securityContext) add :
securityContext:
runAsUser: 0
runAsGroup: 0
fsGroup: 101
FYI : 0 is root. But the fsGroup value is unknown to me. For what I'm doing I don't care but you might.
Now you can do :
strace -s 100000 -e write=1 -e trace=write -p 16
You won't get the permission denied anymore !
BEWARE : This is the Pandora box. Having this in production it NOT recommended.
I was running my code with higher privileges to deal with Ethernet Raw Sockets by setting set capability command in Debian Distribution. I tried the above solution: echo 0 > /proc/sys/kernel/yama/ptrace_scope
or by modifying it in /etc/sysctl.d/10-ptrace.conf but that did not work for me.
Additionally, I also tried with set capabilities command for gdb in installed directory (usr/bin/gdb) and it works: /sbin/setcap CAP_SYS_PTRACE=+eip /usr/bin/gdb.
Be sure to run this command with root privileges.
Jesup's answer is correct; it is due to Linux kernel hardening. In my case, I am using Docker Community for Mac, and in order to do change the flag I must enter the LinuxKit shell using justin cormack's nsenter (ref: https://www.bretfisher.com/docker-for-mac-commands-for-getting-into-local-docker-vm/ ).
docker run -it --rm --privileged --pid=host justincormack/nsenter1
/ # cat /etc/issue
Welcome to LinuxKit
## .
## ## ## ==
## ## ## ## ## ===
/"""""""""""""""""\___/ ===
{ / ===-
\______ O __/
\ \ __/
\____\_______/
/ # cat /proc/sys/kernel/yama/ptrace_scope
1
/ # echo 0 > /proc/sys/kernel/yama/ptrace_scope
/ # exit
Maybe someone has attached this process with gdb.
ps -ef | grep gdb
can't gdb attach the same process twice.
I was going to answer this old question as it is unaccepted and any other answers are not got the point. The real answer may be already written in /etc/sysctl.d/10-ptrace.conf as it is my case under Ubuntu. This file says:
For applications launching crash handlers that need PTRACE, exceptions can
be registered by the debugee by declaring in the segfault handler
specifically which process will be using PTRACE on the debugee:
prctl(PR_SET_PTRACER, debugger_pid, 0, 0, 0);
So just do the same thing as above: keep /proc/sys/kernel/yama/ptrace_scope as 1 and add prctl(PR_SET_PTRACER, debugger_pid, 0, 0, 0); in the debugee. Then the debugee will allow debugger to debug it. This works without sudo and without reboot.
Usually, debugee also need to call waitpid to avoid exit after crash so debugger can find the pid of debugee.
If permissions are a problem, you probably will want to use gdbserver. (I almost always use gdbserver when I gdb, docker or no, for numerous reasons.) You will need gdbserver (Deb) or gdb-gdbserver (RH) installed in the docker image. Run the program in docker with
$ sudo gdbserver :34567 myprogram arguments
(pick a port number, 1025-65535). Then, in gdb on the host, say
(gdb) target remote 172.17.0.4:34567
where 172.17.0.4 is the IP address of the docker image as reported by /sbin/ip addr list run in the docker image. This will attach at a point before main runs. You can tb main and c to stop at main, or wherever you like. Run gdb under cgdb, emacs, vim, or even in some IDE, or plain. You can run gdb in your source or build tree, so it knows where everything is. (If it can't find your sources, use the dir command.) This is usually much better than running it in the docker image.
gdbserver relies on ptrace, so you will also need to do the other things suggested above. --privileged --pid=host sufficed for me.
If you deploy to other OSes or embedded targets, you can run gdbserver or a gdb stub there, and run gdb the same way, connecting across a real network or even via a serial port (/dev/ttyS0).
I don't know what you are doing with LD_PRELOAD or your ptrace function.
Why don't you try attaching gdb to a very simple program? Make a program that simply repeatedly prints Hello or something and use gdb --pid [hello program PID] to attach to it.
If that does not work then you really do have a problem.
Another issue is the user ID. Is the program that you are tracing setting itself to another UID? If it is then you cannot ptrace it unless you are using the same user ID or are root.
I have faced the same problem and try a lot of solution but finally, I have found the solution, but really I don't know what the problem was. First I modified the ptrace_conf value and login into Ubuntu as a root but the problem still appears. But the most strange thing that happened is the gdb showed me a message that says:
Could not attach to process. If your uid matches the uid of the target process, check the setting of /proc/sys/kernel/yama/ptrace_scope, or try again as the root user.
For more details, see /etc/sysctl.d/10-ptrace.conf
warning: process 3767 is already traced by process 3755 ptrace: Operation not permitted.
With ps command terminal, the process 3755 was not listed.
I found the process 3755 in /proc/$pid but I don't understand what was it!!
Finally, I deleted the target file (foo.c) that I try to attach it vid gdb and tracer c program using PTRACE_ATTACH syscall, and in the other folder, I created another c program and compiled it.
the problem is solved and I was enabled to attach to another process either by gdb or ptrace_attach syscall.
(gdb) attach 4416
Attaching to process 4416
and I send a lot of signals to process 4416. I tested it with both gdb and ptrace, both of them run correctly.
really I don't know the problem what was, but I think it is not a bug in Ubuntu as a lot of sites have referred to it, such https://askubuntu.com/questions/143561/why-wont-strace-gdb-attach-to-a-process-even-though-im-root
Extra information
If you wanna make changes in the interfaces such as add the ovs bridge, you must use --privileged instead of --cap-add NET_ADMIN.
sudo docker run -itd --name=testliz --privileged --cap-add=SYS_PTRACE --security-opt seccomp=unconfined ubuntu
If you are using FreeBSD, edit /etc/sysctl.conf, change the line
security.bsd.unprivileged_proc_debug=0
to
security.bsd.unprivileged_proc_debug=1
Then reboot.

Resources