Bug 265008

Summary: 'undefined symbol: environ' when a shared library is built which shouldn't happen according to environ(7)
Product: Base System Reporter: Yuri Victorovich <yuri>
Component: miscAssignee: freebsd-toolchain (Nobody) <toolchain>
Status: Closed DUPLICATE    
Severity: Affects Only Me CC: marklmi26-fbsd
Priority: ---    
Version: 13.1-STABLE   
Hardware: Any   
OS: Any   
URL: https://reviews.freebsd.org/D30842

Description Yuri Victorovich freebsd_committer freebsd_triage 2022-07-03 07:28:35 UTC
The Criterion project (https://github.com/Snaipe/Criterion) fails to build with:
cc  -o src/libcriterion.so.3.2.0 src/libcriterion.so.3.2.0.p/err.c.o src/libcriterion.so.3.2.0.p/mutex.c.o src/libcriterion.so.3.2.0.p/capi_specifiers.c.o src/libcriterion.so.3.2.0.p/capi_stream.c.o src/libcriterion.so.3.2.0.p/compat_alloc.c.o src/libcriterion.so.3.2.0.p/compat_kill.c.o src/libcriterion.so.3.2.0.p/compat_mockfile.c.o src/libcriterion.so.3.2.0.p/compat_path.c.o src/libcriterion.so.3.2.0.p/compat_pipe.c.o src/libcriterion.so.3.2.0.p/compat_process.c.o src/libcriterion.so.3.2.0.p/compat_processor.c.o src/libcriterion.so.3.2.0.p/compat_section.c.o src/libcriterion.so.3.2.0.p/compat_strtok.c.o src/libcriterion.so.3.2.0.p/compat_time.c.o src/libcriterion.so.3.2.0.p/core_abort.c.o src/libcriterion.so.3.2.0.p/core_assert.c.o src/libcriterion.so.3.2.0.p/core_client.c.o src/libcriterion.so.3.2.0.p/core_ordered-set.c.o src/libcriterion.so.3.2.0.p/core_report.c.o src/libcriterion.so.3.2.0.p/core_runner.c.o src/libcriterion.so.3.2.0.p/core_runner_coroutine.c.o src/libcriterion.so.3.2.0.p/core_stats.c.o src/libcriterion.so.3.2.0.p/core_test.c.o src/libcriterion.so.3.2.0.p/csptr_array.c.o src/libcriterion.so.3.2.0.p/csptr_mman.c.o src/libcriterion.so.3.2.0.p/entry_entry.c.o src/libcriterion.so.3.2.0.p/entry_options.c.o src/libcriterion.so.3.2.0.p/entry_params.c.o src/libcriterion.so.3.2.0.p/io_event.c.o src/libcriterion.so.3.2.0.p/io_file.c.o src/libcriterion.so.3.2.0.p/io_json.c.o src/libcriterion.so.3.2.0.p/io_output.c.o src/libcriterion.so.3.2.0.p/io_redirect.c.o src/libcriterion.so.3.2.0.p/io_tap.c.o src/libcriterion.so.3.2.0.p/io_xml.c.o src/libcriterion.so.3.2.0.p/log_logging.c.o src/libcriterion.so.3.2.0.p/log_normal.c.o src/libcriterion.so.3.2.0.p/protocol_connect.c.o src/libcriterion.so.3.2.0.p/protocol_messages.c.o src/libcriterion.so.3.2.0.p/protocol_protocol.c.o src/libcriterion.so.3.2.0.p/string_brz.c.o src/libcriterion.so.3.2.0.p/string_extglobmatch.c.o src/libcriterion.so.3.2.0.p/string_fmt.c.o src/libcriterion.so.3.2.0.p/string_i18n.c.o src/libcriterion.so.3.2.0.p/string_xxd.c.o src/libcriterion.so.3.2.0.p/protocol_criterion.pb.c.o src/libcriterion.so.3.2.0.p/string_diff.c.o src/libcriterion.so.3.2.0.p/core_theories.c.o -Wl,--as-needed -Wl,--no-undefined -Wl,-O1 -shared -fPIC -Wl,--start-group -Wl,-soname,libcriterion.so.3 -fstack-protector-strong -O2 -pipe -fno-omit-frame-pointer -fstack-protector-strong -fno-strict-aliasing -fno-omit-frame-pointer -Wl,-rpath,/usr/local/lib -Wl,-rpath-link,/usr/local/lib subprojects/boxfort/src/libboxfort.a subprojects/nanomsg/libnanomsg.a subprojects/nanopb/libprotobuf_nanopb_static.a -Wl,--exclude-libs,ALL -pthread -lrt -lm /usr/local/lib/libffi.so /usr/local/lib/libgit2.so -lpthread -Wl,--end-group
ld: error: undefined symbol: environ
>>> referenced by sandbox-posix.c



extern is defined in sandbox-posix.c:
> extern char **environ;
so it should just exist and no such error should ever occur.


There was a dedicated bug report for this but I can't find it now.
Comment 1 Yuri Victorovich freebsd_committer freebsd_triage 2022-07-03 07:33:24 UTC
The -Wl,--no-undefined flag triggers it.


Testcase:

$ cat x.c 

extern char **environ;

char** fn() {
	return environ;
}

$ cc --shared -o x.so -fPIC -Wl,--no-undefined  x.c
ld: error: undefined symbol: environ
>>> referenced by x.c
>>>               /tmp/x-0e96b0.o:(fn)
cc: error: linker command failed with exit code 1 (use -v to see invocation)
Comment 2 Mark Millard 2022-07-03 17:05:51 UTC
(In reply to Yuri Victorovich from comment #1)

What about:

QUOTE
An array of strings, called the environment is made available to each
     process by execve(2) when a process begins.
END QUOTE

makes you think a link-time definition binding would be available
for the .so being built so that -Wl,--no-undefined could be used?
Is there some other wording that I missed that implies "shouldn't
happen according to environ(7)" for linking .so files?

environ is implicit/automatic in the likes of:

# more trivial.c
// # cc -o trival trivial.c

int main() {
}

# cc -o trivial trivial.c

# nm trivial | grep environ
0000000000203aa0 B environ

There should end up being only one definition, even when a so
is involved at run time with the program, not separate
definitions in multiple places. In fact:

 # ldd trivial
trivial:
	libc.so.7 => /lib/libc.so.7 (0x200000)
[preloaded]
	[vdso] (0x7fffffffe000)

# nm /lib/libc.so.7 | grep environ
                 U environ

So even /lib/libc.so.7 has it as undefined in order to
pick up the one definition at load time (not link time).
Comment 3 Yuri Victorovich freebsd_committer freebsd_triage 2022-07-03 17:11:26 UTC
(In reply to Mark Millard from comment #2)

Hi Mark,

Every symbol should be resolvable in some way, either through some library or it should "just exist".

environ(7) suggests that it just exists, w/out the need for any libraries. And it does just exists, except when one links some shared library with particular flags.

The provided example is a valid use case of environ, yet it fails without an obvious workaround that doesn't alter link flags.


Yuri
Comment 4 Mark Millard 2022-07-03 17:12:29 UTC
(In reply to Yuri Victorovich from comment #0)

I found:

https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=263265

which has related material.
Comment 5 Yuri Victorovich freebsd_committer freebsd_triage 2022-07-03 17:15:12 UTC
(In reply to Mark Millard from comment #4)

Thanks!
Comment 6 Yuri Victorovich freebsd_committer freebsd_triage 2022-07-03 17:16:14 UTC

*** This bug has been marked as a duplicate of bug 263265 ***
Comment 7 Mark Millard 2022-07-03 17:17:00 UTC
(In reply to Yuri Victorovich from comment #3)

(In reply to Yuri Victorovich from comment #3)

See https://reviews.freebsd.org/D30842 for the
FreeBSD specific details of why not (as stands).