I have simple code files and Makefile the generates some executable files. Now I am having problem with running it. First that the output of gcc is not giving me .o file with execution permission. Which is surprising, at the bottom is my makefile I ran into these issues below.
With ls -lh command it says I only have maximum read and write permission to a writeshmem.o. same for all files in the directory. Even though I don't remember setting any system wide permission for outputting .o file without execution permission from gcc. And I DO NOT REMEMBER REVOKING ROOT USER PERMISSION.
root#fawad:/home/fawad/Desktop/Shared# ls -lh
total 44K
-rw-r--r-- 1 root root 263 Sep 6 14:07 Makefile
-rw-r--r-- 1 root root 359 Sep 6 14:10 destroy_shmem.c
-rw-r--r-- 1 root root 3.9K Sep 6 14:10 destroy_shmem.o
-rw-r--r-- 1 root root 381 Sep 6 13:40 readshmem.c
-rw-r--r-- 1 root root 4.1K Sep 6 14:14 readshmem.o
-rw-r--r-- 1 root root 1014 Sep 6 11:58 shared_memory.c
-rw-r--r-- 1 root root 267 Sep 6 14:09 shared_memory.h
-rw-r--r-- 1 root root 490 Sep 6 13:30 writeshmem.c
-rw-r--r-- 1 root root 4.2K Sep 6 14:14 writeshmem.o
As u can see there is no execution x
After above when I gave permission with
root#fawad:/home/fawad/Desktop/Shared# chmod +rwx writeshmem.o
I got this error
root#fawad:/home/fawad/Desktop/Shared# ./writeshmem.o
bash: ./writeshmem.o: cannot execute binary file: Exec format error
What that above error even means. It make no sense to me how giving permission to a file messed up with the EXecution format of the file. Someone can please explain why it matters for a file to cause this error. I only change the permission.
Makefile
CC=gcc
CFLAGS=-g -Wall
OBJS=shared_memory.o
EXE=writeshmem.o readshmem.o destroy_shmem.o
all: $(EXE)
%.o: %.o $(OBJS)
$(CC) $(CFLAGS) $< $(OBJS) -o $#
%.o: %.c %.h
$(CC) $(CFLAGS) -c $< -o $#
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $#
clean:
rm .o $(EXE)
Update
after reading comment(You should remove the .o from the executable names) by kaylum I removed .o from executables in makefile But I still get error
root#fawad:/home/fawad/Desktop/Shared# ./writeshmem
bash: ./writeshmem: Permission denied
and same output from ls -lh
-rw-r--r-- 1 root root 251 Sep 6 14:59 Makefile
-rw-r--r-- 1 root root 3.9K Sep 6 15:00 destroy_shmem
-rw-r--r-- 1 root root 359 Sep 6 14:10 destroy_shmem.c
-rw-r--r-- 1 root root 4.1K Sep 6 15:00 readshmem
-rw-r--r-- 1 root root 381 Sep 6 13:40 readshmem.c
-rw-r--r-- 1 root root 1014 Sep 6 11:58 shared_memory.c
-rw-r--r-- 1 root root 267 Sep 6 14:09 shared_memory.h
-rw-r--r-- 1 root root 4.2K Sep 6 15:00 writeshmem
-rw-r--r-- 1 root root 490 Sep 6 13:30 writeshmem.c
everything including writeshmem is still with only rw permission and without x
I have tried lot by searching goggle to solve it.but unable to compile as per documentation in below GitHub.
Pg_Audit Extention
below is the env. for my postgres user.
export PGHOME=/var/lib/pgsql/
export PGDATA=/var/lib/pgsql/11/data/
export PGDATABASE=postgres
export PGUSER=postgres
export PGPORT=xxxx
export PGLOCALEDIR=/usr/pgsql-11/share/
Following below STEPS. I am using to make install/compile.
-bash-4.2$ pwd
/var/lib/pgsql
-bash-4.2$ cd pgaudit-REL_11_STABLE/
-bash-4.2$ pwd
/var/lib/pgsql/pgaudit-REL_11_STABLE
-bash-4.2$ ll
total 528
drwx------. 2 postgres postgres 25 May 23 2019 expected
-rw-------. 1 postgres postgres 171 May 23 2019 LICENSE
-rw-------. 1 postgres postgres 548 May 23 2019 Makefile
-rw-------. 1 postgres postgres 175 May 23 2019 pgaudit--1.3--1.3.1.sql
-rw-------. 1 postgres postgres 615 May 23 2019 pgaudit--1.3.1.sql
-rw-------. 1 postgres postgres 63517 May 23 2019 pgaudit.c
-rw-------. 1 postgres postgres 35 May 23 2019 pgaudit.conf
-rw-------. 1 postgres postgres 145 May 23 2019 pgaudit.control
-rw-------. 1 postgres postgres 266312 Feb 9 11:48 pgaudit.o
-rwx------. 1 postgres postgres 157624 Feb 9 11:48 pgaudit.so
-rw-------. 1 postgres postgres 17312 May 23 2019 README.md
drwx------. 2 postgres postgres 25 May 23 2019 sql
drwx------. 2 postgres postgres 25 May 23 2019 test
-bash-4.2$
-bash-4.2$ make check USE_PGXS=1
"make check" is not supported.
Do "make install", then "make installcheck" instead.
-bash-4.2$ make install
/opt/rh/llvm-toolset-7/root/usr/bin/clang -Wno-ignored-attributes -fno-strict-aliasing -fwrapv -O2 -I. -I./ -I/usr/pgsql-11/include/server -I/usr/pgsql-11/in
clude/internal -D_GNU_SOURCE -I/usr/include/libxml2 -I/usr/include -flto=thin -emit-llvm -c -o pgaudit.bc pgaudit.c
make: /opt/rh/llvm-toolset-7/root/usr/bin/clang: Command not found
make: *** [pgaudit.bc] Error 127
-bash-4.2$
I also copied pg_audit.so
scp -r /var/lib/pgsql/pgaudit-REL_11_STABLE/pgaudit.so /usr/pgsql-11/share/contrib/
cd /usr/pgsql-11/share/contrib/
/usr/pgsql-11/share/contrib
-bash-4.2$ ll
total 176
-rwx------. 1 root root 157624 Feb 10 07:43 pgaudit.so
-rw-------. 1 root root 14875 Feb 10 08:10 pgaudit.sql
-rw-r--r--. 1 root root 1644 Aug 7 2019 sepgsql.sql
-bash-4.2$ pwd
/usr/pgsql-11/share/contrib
also when i use below command getting below error.
-bash-4.2$ make install PGUSER=postgres USE_PGXS=1 PATH=/usr/pgsql-11/bin:{PATH}
/opt/rh/llvm-toolset-7/root/usr/bin/clang -Wno-ignored-attributes -fno-strict-aliasing -fwrapv -O2 -I. -I./ -I/usr/pgsql-11/include/server -I/usr/pgsql-11/in
clude/internal -D_GNU_SOURCE -I/usr/include/libxml2 -I/usr/include -flto=thin -emit-llvm -c -o pgaudit.bc pgaudit.c
make: /opt/rh/llvm-toolset-7/root/usr/bin/clang: Command not found
make: *** [pgaudit.bc] Error 127
I am missing something related to copying or setting env. please help me.
Edit: I go through suggested by Laurenz Albe in below answer. now getting below error.
[root#ip- pgaudit-REL_11_STABLE]# /usr/bin/make install PGUSER=postgres USE_PGXS=1 with_llvm=no make -e PATH=/usr/pgsql-11/bin:{PATH}
/usr/bin/mkdir -p '/usr/lib64/pgsql'
/usr/bin/mkdir -p '/usr/share/pgsql/extension'
/usr/bin/mkdir -p '/usr/share/pgsql/extension'
/bin/sh /usr/lib64/pgsql/pgxs/src/makefiles/../../config/install-sh -c -m 755 pgaudit.so '/usr/lib64/pgsql/pgaudit.so'
/usr/lib64/pgsql/pgxs/src/makefiles/../../config/install-sh: line 75: uname: command not found
/usr/lib64/pgsql/pgxs/src/makefiles/../../config/install-sh: line 326: sed: command not found
/usr/lib64/pgsql/pgxs/src/makefiles/../../config/install-sh: line 461: exec: cp: not found
/usr/lib64/pgsql/pgxs/src/makefiles/../../config/install-sh: line 1: rm: command not found
make: *** [install-lib-shared] Error 1
i have checked in /usr/bin all required utilities are available.
[root#ip- pgaudit-REL_11_STABLE]# ls -lrth /usr/bin/ | grep uname
lrwxrwxrwx. 1 root root 7 Jun 18 2019 uname26 -> setarch
-rwxr-xr-x. 1 root root 29K Jan 23 19:07 uname
[root#ip pgaudit-REL_11_STABLE]# ls -lrth /usr/bin/ | grep sed
-rwxr-xr-x. 1 root root 75K Aug 1 2018 sed
-rwxr-xr-x. 2 root root 53K Feb 19 2019 psed
[root#ip pgaudit-REL_11_STABLE]# ls -lrth /usr/bin/ | grep exec
-rwxr-xr-x. 1 root root 16K Aug 2 2018 msgexec
[root#ip pgaudit-REL_11_STABLE]# ls -lrth /usr/bin/ | grep rm
-rwxr-xr-x. 1 root root 41K Jan 23 19:07 rmdir
Now getting below error. I am really not able to understand what error want to say. please help.
[root# pgaudit-REL_11_STABLE]# make install PGUSER=postgres USE_PGXS=1 PATH=/usr/pgsql-11/bin:$PATH with_llvm=no make -e
/usr/bin/mkdir -p '/usr/lib64/pgsql'
/usr/bin/mkdir -p '/usr/share/pgsql/extension'
/usr/bin/mkdir -p '/usr/share/pgsql/extension'
/bin/sh /usr/lib64/pgsql/pgxs/src/makefiles/../../config/install-sh -c -m 755 pgaudit.so '/usr/lib64/pgsql/pgaudit.so'
/bin/sh /usr/lib64/pgsql/pgxs/src/makefiles/../../config/install-sh -c -m 644 ./pgaudit.control '/usr/share/pgsql/extension/'
/bin/sh /usr/lib64/pgsql/pgxs/src/makefiles/../../config/install-sh -c -m 644 ./pgaudit--1.3.1.sql ./pgaudit--1.3--1.3.1.sql '/usr/share/pgsql/extension/'
make: *** No rule to make target `make'. Stop.
[root# pgaudit-REL_11_STABLE]#
You should install clang so that PGXS can build the byte code.
If you don't need JIT, a workaround is to build with
with_llvm=no make -e
To add /usr/pgsql-11/bin to the PATH, run
PATH=/usr/pgsql-11/bin:$PATH with_llvm=no make -e
I am trying to make use of a library, https://github.com/go-steem/rpc, that makes use of some C code, which references a library.
The C library can be found here, https://github.com/bitcoin-core/secp256k1
I followed the steps to get that installed
$ ./autogen.sh
$ ./configure
$ make
$ ./tests
$ sudo make install # optional
And have this output;
$ sudo make install
Password:
CC src/libsecp256k1_la-secp256k1.lo
CCLD libsecp256k1.la
CC src/tests-tests.o
CCLD tests
CC src/exhaustive_tests-tests_exhaustive.o
CCLD exhaustive_tests
build-aux/install-sh -c -d '/usr/local/lib'
/bin/sh ./libtool --mode=install /usr/bin/install -c libsecp256k1.la '/usr/local/lib'
libtool: install: /usr/bin/install -c .libs/libsecp256k1.0.dylib /usr/local/lib/libsecp256k1.0.dylib
libtool: install: (cd /usr/local/lib && { ln -s -f libsecp256k1.0.dylib libsecp256k1.dylib || { rm -f libsecp256k1.dylib && ln -s libsecp256k1.0.dylib libsecp256k1.dylib; }; })
libtool: install: /usr/bin/install -c .libs/libsecp256k1.lai /usr/local/lib/libsecp256k1.la
libtool: install: /usr/bin/install -c .libs/libsecp256k1.a /usr/local/lib/libsecp256k1.a
libtool: install: chmod 644 /usr/local/lib/libsecp256k1.a
libtool: install: /usr/bin/ranlib /usr/local/lib/libsecp256k1.a
build-aux/install-sh -c -d '/usr/local/include'
/usr/bin/install -c -m 644 include/secp256k1.h '/usr/local/include'
build-aux/install-sh -c -d '/usr/local/lib/pkgconfig'
/usr/bin/install -c -m 644 libsecp256k1.pc '/usr/local/lib/pkgconfig'
I try to run the upvote example from that Go library, go-steem/rpc/examples/upvote/ and get the following output;
$ go run main.go
# github.com/go-steem/rpc/transactions
../../transactions/signing.c:5:10: fatal error: 'secp256k1.h' file not found
Already it feels as though the wheels are falling off...
Please bear with me as I do not develop in C, so I get a bit hack-y.
After much reading, and googling I decide to copy the files from the 'include' directory where I compiled libsecp256k1 into the same directory as the error is originating from.
You can see the files are not there;
$ ls -la ../../transactions/
total 48
drwxr-xr-x 8 shaunmorrow staff 272 May 8 18:09 .
drwxr-xr-x 15 shaunmorrow staff 510 May 8 18:09 ..
-rw-r--r-- 1 shaunmorrow staff 256 Apr 27 17:53 chains.go
-rw-r--r-- 1 shaunmorrow staff 3731 May 8 18:09 signed_transaction.go
-rw-r--r-- 1 shaunmorrow staff 1849 May 8 18:09 signed_transaction_test.go
-rw-r--r-- 1 shaunmorrow staff 3075 Apr 27 17:53 signing.c
-rw-r--r-- 1 shaunmorrow staff 408 Apr 27 17:53 signing.h
-rw-r--r-- 1 shaunmorrow staff 1049 May 8 18:09 transactions.go
and after the copy;
$ ls -la ../../transactions/
total 128
drwxr-xr-x 11 shaunmorrow staff 374 Jul 18 19:08 .
drwxr-xr-x 15 shaunmorrow staff 510 May 8 18:09 ..
-rw-r--r-- 1 shaunmorrow staff 256 Apr 27 17:53 chains.go
-rw-r--r-- 1 shaunmorrow staff 27071 Jul 18 19:08 secp256k1.h
-rw-r--r-- 1 shaunmorrow staff 1014 Jul 18 19:08 secp256k1_ecdh.h
-rw-r--r-- 1 shaunmorrow staff 4700 Jul 18 19:08 secp256k1_recovery.h
-rw-r--r-- 1 shaunmorrow staff 3731 Jul 18 19:05 signed_transaction.go
-rw-r--r-- 1 shaunmorrow staff 1849 May 8 18:09 signed_transaction_test.go
-rw-r--r-- 1 shaunmorrow staff 3075 Apr 27 17:53 signing.c
-rw-r--r-- 1 shaunmorrow staff 408 Apr 27 17:53 signing.h
-rw-r--r-- 1 shaunmorrow staff 1049 May 8 18:09 transactions.go
Now I get a new error;
$ go run main.go
# github.com/go-steem/rpc/transactions
ld: library not found for -lsecp256k1
clang: error: linker command failed with exit code 1 (use -v to see invocation)
This has me reading and googling some more,
Finally I get even more hack-y and change transactions.go;
// #cgo LDFLAGS: -lsecp256k1
// #include <stdlib.h>
// #include "signing.h"
import "C"
becomes
// #cgo LDFLAGS: -L/usr/local/lib
// #include <stdlib.h>
// #include "signing.h"
import "C"
which fails, output on that later
I also try;
// #cgo LDFLAGS: -L/usr/local/lib -I/usr/local/include
// #include <stdlib.h>
// #include "signing.h"
import "C"
and copy the .h files into the /usr/local/include directory.
None of this works and now I am stuck with an error like this
$ go run main.go
# github.com/go-steem/rpc/transactions
ld: library not found for -lsecp256k1
clang: error: linker command failed with exit code 1 (use -v to see invocation)
ShaunsSePc-2:upvote shaunmorrow$ go run main.go
# github.com/go-steem/rpc/transactions
Undefined symbols for architecture x86_64:
"_secp256k1_context_create", referenced from:
_sign_transaction in signing.o
_verify_recoverable_signature in signing.o
"_secp256k1_context_destroy", referenced from:
_sign_transaction in signing.o
_verify_recoverable_signature in signing.o
"_secp256k1_ec_pubkey_serialize", referenced from:
_verify_recoverable_signature in signing.o
"_secp256k1_ecdsa_recover", referenced from:
_verify_recoverable_signature in signing.o
"_secp256k1_ecdsa_recoverable_signature_convert", referenced from:
_verify_recoverable_signature in signing.o
"_secp256k1_ecdsa_recoverable_signature_parse_compact", referenced from:
_verify_recoverable_signature in signing.o
"_secp256k1_ecdsa_recoverable_signature_serialize_compact", referenced from:
_sign_transaction in signing.o
"_secp256k1_ecdsa_sign_recoverable", referenced from:
_sign_transaction in signing.o
"_secp256k1_ecdsa_verify", referenced from:
_verify_recoverable_signature in signing.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
At this point I really have no idea how to continue.
As you can see I am not experienced in C at all and have no idea how to test if the library libsecp256k1 is even installed properly!
This is where I ended up, but it's highly likely I took a wrong turn early in my journey, I would appreciate any help given as I have been struggling with this for a few nights already now :(
Not sure whats needed so here some env variables
$ go env
GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH="/Users/shaunmorrow/Work/go/"
GORACE=""
GOROOT="/usr/local/go"
GOTOOLDIR="/usr/local/go/pkg/tool/darwin_amd64"
GCCGO="gccgo"
CC="clang"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/86/hlqptn5101z5bcydjz05qy8m0000gn/T/go-build689438019=/tmp/go-build -gno-record-gcc-switches -fno-common"
CXX="clang++"
CGO_ENABLED="1"
PKG_CONFIG="pkg-config"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
Version is go version go1.8.3 darwin/amd64 with no old versions lying around.
Thanks!
Your problem is twofold:
Improperly configured libsecp256k1 package
Your C compiler not searching /usr/local directories for installed headers/libs
Fixing the improperly libsecp256k1 configured package
Your "undefined symbols" issue when it comes to linking C libraries sometimes points to an improperly configured package (in the sense of an Autotools package or a CMake package, not a Go package). Running ./configure --help, I see there is an option named --enable-module-recovery. Judging by names like _secp256k1_ecdsa_sign_recoverable and _secp256k1_ecdsa_recover, you need to add that option when configuring, meaning instead of executing the simpler ./configure, you should execute this:
./configure --enable-module-recovery
Is the C compiler broken?
Since the secp256k1.h header file isn't found in /usr/local/include, despite the fact that the header file most definitely exists after sudo make install is finished, it means your compiler doesn't search /usr/local.
Barring any fixes in the linked question, you can work around the issue by altering the source of the Go package as needed to add/modify the CFLAGS and LDFLAGS used when dealing with import "C" statements like this:
// #cgo CFLAGS: -I/usr/local/include
// #cgo LDFLAGS: -L/usr/local/lib -lsecp256k1
// #include <secp256k1.h>
import "C"
If you have pkg-config installed, you can use that instead of setting CFLAGS and LDFLAGS manually:
Export the PKG_CONFIG_PATH environment variable with a custom set of paths. Because no prefix (i.e. directory serving as the install root) was specified, /usr/local is assumed, meaning /usr/local/include will contain headers and /usr/local/lib will contain libraries. This means you need to export PKG_CONFIG_PATH on your command line as in export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:/usr/local/share/pkgconfig:/usr/lib/pkgconfig:/usr/share/pkgconfig. The default setting of PKG_CONFIG_PATH when unset includes /usr/lib/pkgconfig and /usr/share/pkgconfig in that order on Linux and are specified as a fallback for other packages that might be used, though it may not be necessary in this case. The default set of paths may differ on OS X, so consult your pkg-config man page for reference.
Use // #cgo pkg-config: libsecp256k1, and CFLAGS and LDFLAGS will be set as necessary without you needing to do anything to them. Since not all systems have pkg-config installed, relying on this is perhaps a bad idea if you want a package to remain portable. Then again, I think it'd be preferable to the mess you dealt with since pkg-config simply wouldn't be found.
Change to the upvote directory and type make to build a working upvote binary.
Additional customization
Custom prefix
If you use something other than /usr/local as your prefix (e.g. ./configure --enable-module-recovery --prefix=/opt/libsecp256k1), then you'll need to adjust some things accordingly:
// #cgo CFLAGS: -I/opt/libsecp256k1/include
// #cgo LDFLAGS: -L/opt/libsecp256k1/lib -lsecp256k1
// #include "secp256k1.h"
import "C"
// or just use pkg-config and export the PKG_CONFIG_PATH environment
// variable containing the following paths:
// /opt/libsecp256k1/lib/pkgconfig
// /opt/libsecp256k1/share/pkgconfig
// /usr/lib/pkgconfig
// /usr/share/pkgconfig
You'll also need to modify the provided Makefile in the upvote directory to set the runtime path of the binary that gets built, else libsecp256k1.0.dylib will not be found:
# If you copy and paste this, replace the spaces in front of `go build`
# with a single horizontal tab character, else `make` will fail.
#
# Note that the "ldflags" specified are for the Go linker (go tool link),
# not the system's linker (ld).
build:
go build -ldflags="-r /opt/libsecp256k1/lib"
For more information about working with cgo, check out the following resources:
"C? Go? Cgo!" introduction to cgo on The Go Blog
Cgo documentation
I compile and link a simple program:
# gcc a.c -pthread
# ldd a.out
linux-vdso.so.1 (0x00007ffc4ddf2000)
libpthread.so.0 => /usr/lib/libpthread.so.0 (0x00007fbb75e12000)
libc.so.6 => /usr/lib/libc.so.6 (0x00007fbb75a6e000)
/lib64/ld-linux-x86-64.so.2 (0x00007fbb76030000)
The program links the shared library. But from gcc manual:
-llibrary
-l library
......
The linker searches a standard list of directories for the library,
which is actually a file named liblibrary.a. The linker then uses this
file as if it had been specified precisely by name.
......
It seems the program should link the static library. I find there are both static and dynamic libraries:
# ls -alt /usr/lib/libpthread*
-rw-r--r-- 1 root root 392576 Mar 6 22:06 /usr/lib/libpthread.a
lrwxrwxrwx 1 root root 18 Mar 6 22:06 /usr/lib/libpthread.so.0 -> libpthread-2.25.so
-rw-r--r-- 1 root root 1748 Mar 6 22:06 /usr/lib/libpthread_nonshared.a
-rwxr-xr-x 1 root root 146824 Mar 6 22:06 /usr/lib/libpthread-2.25.so
-rw-r--r-- 1 root root 222 Mar 6 22:06 /usr/lib/libpthread.so
Why does gcc choose the dynamic one? BTW, is there any difference when using -lpthread and pthread as the link option during compiling program?
For some reason one of my directories has started producing
executables. By this I mean that new files in that directory are
a+x (but not, for example in the parent directory):
$ ls -ld .
drwxrwsr-x 2 me me 45 Dec 5 10:22 ./
drwxrwsr-x 10 me me 13 Dec 5 10:22 ../
$ rm -f test
$ touch test
$ ls -l test
-rwxrwxr-x 1 me me 0 Dec 5 10:25 test*
$ cd ..
$ rm -f test
$ touch test
$ ls -l test
-rw-rw-r--+ 1 me me 0 Dec 5 10:26 test
Also, notice the + at the end of the second permissions line, is it significant?
I know it cannot be a umask thing...but it's set at 0002.
How can I turn off this behavior?
EDIT:
In response to an answer below I ran the following (in the parent dir):
$ touch test
$ getfacl test
# file: test
# owner: me
# group: me
user::rw-
group::rw-
mask::rwx
other::r--
Why do I have this mask? Is this the right value for it? How can I change it?
The + indicates the presence of one or more ACLs on the entry. getfacl test will show you more information. The oddity with the apparent executability of new files may be related to the ACLs in the parent directory, but we'd have to see what they are to know for sure...