Can I get line number or stack trace from gtkmm and glibmm runtime diagnostic messages? - glib

I'm writing a toy program using gtkmm and glibmm, which are C++ bindings for GTK and Glib. I'm getting some runtime diagnostic messages. They look like this:
(process:2933): GLib-GObject-CRITICAL **: 16:19:16.920: g_object_set_qdata_full: assertion 'quark > 0' failed
The heading format already include pid and filename most of the time. However, I'd also like to see some line numbers of the corresponding source. Is it possible?
Please don't read this into a form of X-Y question, or don't fix on a particular message. Since I periodically run into - and eventually manage to mend - many of them.

As is said in Running GLib Applications, setting env G_DEBUG to include "fatal-warnings" or "fatal-criticals" will let the program raise a signal SIGTRAP whenever such a diagnostic is encountered. Catching this signal in a debugger may help to look into the stack, etc.
Example usage:
# to dump stack upon first critical diagnostic and quit
G_DEBUG=fatal-criticals gdb -batch -ex "run" -ex "i stack" ./a.out
# or upon first and second critical and or warning diagnostic whichever comes earlier
G_DEBUG=fatal-warnings gdb -batch -ex "run" -ex "i stack" -ex "cont" -ex "i stack" ./a.out

Related

Why can't ld called from MSYS find (existing static) library when arguments are read from a response #file containing backslashes?

This is basically the same issue as in mingw ld cannot find some library which is exist in the search path, MinGW linker can't find MPICH2 libraries - and I'm aware that there are heaps of posts on StackOverflow regarding the issue of static and dynamic linking with MinGW - but I couldn't find anything that explains how I can troubleshoot.
I am building a project with a huge linker command like (via g++) on MinGW, in a MSYS2 shell (git-bash.exe). The process fails with, among others:
/z/path/to/../../../../i686-w64-mingw32/bin/ld.exe: cannot find -lssl
I add -Wl,--verbose to the g++ linker call (to be passed to ld), and I can see for the -L/z/path/to/libs/openssl/lib/mingw -lssl:
...
attempt to open /z/path/to/libs/openssl/lib/mingw/libssl.a failed
...
/z/path/to/libs/openssl/lib/mingw/ssl.dll failed
attempt to open /z/path/to/libs/openssl/lib/mingw\libssl.a failed
...
But this is weird, because the file exists?
$ file /z/path/to/libs/openssl/lib/mingw/libssl.a
/z/path/to/libs/openssl/lib/mingw/libssl.a: current ar archive
(... and it was built with the same compiler on the same machine)?
Weirdly, once it attempts to open with forward slash .../libssl.a, once with backslash ...\libssl.a - but at least the first path checks out in a bash shell, as shown above?
It gets even worse if I try to specify -l:libssl.a -- or if I specify -L/z/path/to/libs/openssl/lib/mingw -Wl,-Bstatic -lssl -- instead; then all attempts to open are with a backslash:
...
attempt to open /z/path/to/scripts/other/build/openssl/build/mingw/lib\libssl.a failed
attempt to open /z/path/to/libs/openssl/lib/mingw\libssl.a failed
...
To top it all off, if I look it up manually through the command line using ld, it is found ?!:
$ ld -L/z/path/to/libs/openssl/lib/mingw -lssl --verbose
attempt to open Z:/path/to/libs/openssl/lib/mingw/libssl.dll.a failed
attempt to open Z:/path/to/libs/openssl/lib/mingw/ssl.dll.a failed
attempt to open Z:/path/to/libs/openssl/lib/mingw/libssl.a succeeded
Does anyone have an idea why this happens, and how can I get ld to finally find these libraries? Or rather - how can I troubleshoot, and understand why these libraries are not found, when they exist at the paths where ld tries to open them?
OK, found something more - not sure if this is a bug; but my problem is that I'm actually reading arguments from a file (otherwise I get g++: Argument list too long). So, to simulate that:
$ echo " -Wl,--verbose -L/z/path/to/libs/openssl/lib/mingw -lssl -lcrypto " > tmcd3
$ g++ #tcmd3 2>&1 | grep succeeded | grep ssl
# nothing
$ g++ `cat tcmd3` 2>&1 | grep succeeded | grep ssl
attempt to open Z:/path/to/libs/openssl/lib/mingw/libssl.a succeeded
attempt to open Z:/path/to/libs/openssl/lib/mingw/libcrypto.a succeeded
... it turns out, if the very same arguments are fed on the command line, then static library lookup succeeds - but if the arguments are read from file through the # at-sign, then static library lookup fails?! Unfortunately, I cannot use on my actual project, since even with cat, I'd still get g++: Argument list too long ... So how can I fix this?
MSYS has special handling of directories as arguments when they are used in the shell. This translates e.g. /<drive_letter>/blabla to the proper Windows style paths. This is to accomodate Unix programs that don't handle Z: style directory root.
What you see here is that MSYS isn't performing this interpretation for string read from a file. When you think about it, it's very logical, but as you have experienced first-hand, also sometimes annoying.
Long story short: don't put Unix style paths in files with command arguments. Instead, pass them through e.g. cygpath -w, which works in MSYS2 (which should be the MSYS that Git for Windows 2+ comes with).
Ok, with some more experiments, I noticed that:
-L/z/path/to/libs/openssl/lib/mingw, the Unix path specification, tends to fail - while if we specify the same, except starting with a Windows drive letter, that is:
-LZ:/path/to/libs/openssl/lib/mingw, then things work - also from an arguments file with # at-sign:
$ echo " -Wl,--verbose -LZ:/path/to/libs/openssl/lib/mingw -lssl -lcrypto " > tmcd3
$ g++ #tcmd3 2>&1 | grep succeeded | grep ssl
attempt to open Z:/path/to/libs/openssl/lib/mingw/libssl.a succeeded
attempt to open Z:/path/to/libs/openssl/lib/mingw/libcrypto.a succeeded
I guess, since the shell is MSYS2/git-bash.exe, entering full POSIX paths on the shell with /z/... is not a problem, because the shell will convert them - but in a file, there is nothing to convert them, so we must use Windows/MingW convention to specify them...

GNU Parallel: suppress warning when input is read from terminal

When input is read from terminal, GNU Parallel always displays a warning:
parallel: Warning: Input is read from the terminal. Only experts do this on purpose. Press CTRL-D to exit.
But sometimes I do want to read from terminal (e.g., when I'm copy & pasting stuff from elsewhere entry by entry). Is it possible to turn off this warning? I couldn't find such an option in man parallel or man parallel_tutorial.
Note that I don't want a cheap solution like 2>/dev/null, since warning messages from other programs will be turned off, too. For instance, consider the following simple script:
#!/bin/bash
function print12 () {
echo "printing $1 to stdout"
echo "printing $1 to stderr" >/dev/stderr
}
export -f print12
SHELL=/bin/bash parallel -k print12 2>/dev/null
Messages printed to stderr will all be suppressed.
Just realized that I can do a cat or some read </dev/tty to achieve my desired effect. But let's just focus on the original question.
It cannot be turned off. But see it as a praise: Since you are doing it on purpose, you are an expert (at least in the eyes of GNU Parallel).
As it is just a warning, you are free to paste your arguments and have them run: The warning does not stop GNU Parallel from reading your input.
If you really do not like the warning:
cat | parallel ...

LLVM bug building synthetic CPU for nostalgic childhood game (register asm global variable)

I've been trying to compile syn64k--for use in Executor, to run System's Twilight (a game I played as a kid). I'm doing this on my macbook pro (lion 10.7.4 with the latest Xcode and command line tools). I mapped CC to gcc -m32 to fix a couple problems I was having, but I got the following:
Making all in native/i386
make[2]: Nothing to be done for `all'.
outgoing=;\
gcc -m32 -maccumulate-outgoing-args -c -x c /dev/null 2> /dev/null && outgoing=-maccumulate-outgoing-args; \
gcc -m32 -S -O2 -fomit-frame-pointer -Wall -static -fno-defer-pop -Wno-unused\ -I./include -I./../include -I. -I../include $outgoing syn68k.c -o ./syn68k.s
syn68k.c: In function ‘s68k_handle_opcode_0x07A3’:
syn68k.c:52968: internal compiler error: in EmitLV_DECL, at llvm-convert.cpp:7475
Please submit a full bug report,
with preprocessed source if appropriate.
See <URL:http://developer.apple.com/bugreporter> for instructions.
make[2]: *** [syn68k.o] Error 1
make[1]: *** [all-recursive] Error 1
make: *** [all-recursive] Error 1
I went to URL, and it doesn't look like a place to really put a bug report about LLVM. I the file 'syn68k.c' is about 50k lines long after the preprocessor is done with it, so I really don't thing I can make a reproducible test case to show the bug.
Turns out this issue is already on the github project (it is the only issue listed, ha). MaddTheSane says that this happens because clang does not support global register variables (as I verified here).
I don't really have much more than a basic understanding of how compilation works after you type make, so is there a way I can skip clang or something like that? What do you suggest?
Unfortunately, you need to use gcc, not llvm-gcc to compile this program. The LLVM backend of llvm-gcc does not support global register variables. Switching to clang won't help because it too will choke on the global register variables, for the same reason.
you definitely can skip building clang if its not necessary for what using llvm for.
llvm uses cmake for configuration and the generation of makefiles. you can modify the .cmake files to create a configuration that disables any modules you don't want to create.
http://developer.apple.com/bugreporter is definitely the right place to report a bug against any compiler distributed by Apple, even if it may not look like it. That said, there's no point to filing a bug report against anything other than clang. (BTW, the size of the testcase doesn't really matter.)
If you don't know enough C to hack the source code, it might be worth a shot to grab a newer version of gcc from macports or something like that.

not output exception stack trace in EUnit

I'm write a test with EUnit, but not anything exception detail output in console.
exp_test() ->
?assertEqual(0, 1/0).
Run this module:exp_test() in the Erlang Shell output following
** exception error: bad argument in an arithmetic expression
in function exp_test:'-exp_test/0-fun-0-'/1 (src/test/eunit/xxx_test.erl, line 8)
But in EUnit output following
> eunit:test(xxx).
> xxx_test: exp_test...*failed*
::badarith
EUnit not output anything exception trace info
Im trying the verbose config in eunit, but no effect.
I want to output some exception detail in eunit test result.
Thanks~
The problem seems to be that the version of eunit shipped with R15 does not understand the new stack trace format in R15. This has been fixed in the development version of eunit: github.com/richcarl/eunit
For example:
Eshell V5.10 (abort with ^G)
1> eunit:test(fun() -> (fun() -> exit(foo), ok end)() end).
erl_eval: expr...*failed*
in function erl_eval:do_apply/6 (erl_eval.erl, line 576)
in call from erl_eval:exprs/5 (erl_eval.erl, line 118)
**exit:foo
I hope this will make it into the next release of OTP R15.
This is a known problem in eunit as released in R15B and R15B01. This has been fixed in release R15B02. If you're stuck with an earlier version, you can download and apply a patch:
A workaround for releases before R15B02
You can fix the problem in your local installation by recompiling the affected module:
Download and unpack the Erlang/OTP sources, if you don't have them already.
wget http://www.erlang.org/download/otp_src_R15B01.tar.gz
tar xzf otp_src_R15B01.tar.gz
cd otp_src_R15B01
Download and apply the patch.
wget -O eunit-stacktrace.patch https://github.com/erlang/otp/commit/73b94a990bb91fd263dace4ccbaef6ff727a9637.patch
patch -p1 < eunit-stacktrace.patch
Recompile eunit_lib.erl.
cd lib/eunit
erlc -o ebin -I include src/eunit_lib.erl
Copy the new eunit_lib.beam over the old one (usually somewhere below /usr/local).
ls /usr/local/lib/erlang/lib/eunit-2.2.2/ebin/
# check that eunit_lib.beam is actually there
sudo cp ebin/eunit_lib.beam /usr/local/lib/erlang/lib/eunit-2.2.2/ebin/
Eunit is quite old and while it is officially maintained by the OTP team at Ericsson, it is usually uncared for. Eunit currently has the bad habit of eating up stack traces, and hasn't been updated for R15's line numbers in exceptions.
I wouldn't argue that "that's how it's supposed to work". No sane test tool should hide exception details and line numbers for you.
A trick I like to use is ?debugVal(catch expr) where expr is either a begin end block
or a call to the failing function. For example, ?debugVal(catch begin 1 = 2 end) will output a stacktrace in your tests.

Why does my erlang build fail with a core dump on Solaris Sparc?

(I have the answer to this already; I'm going to answer my own question so that I can share what I've learned and save someone else this trouble in the future)
When I attempt to build Erlang on Solaris 10 Sparcv9, the build fails partway through:
cd lib && \
ERL_TOP=/var/tmp/pkgbuild-0/erlang/sparcv9/erlang-otp-73b4221 PATH=/var/tmp/pkgbuild-0/erlang/sparcv9/erlang-otp-73b4221/bootstrap/bin:${PATH} \
make opt SECONDARY_BOOTSTRAP=true
make[1]: Entering directory `/var/tmp/pkgbuild-0/erlang/sparcv9/erlang-otp-73b4221/lib'
make[2]: Entering directory `/var/tmp/pkgbuild-0/erlang/sparcv9/erlang-otp-73b4221/lib/hipe'
=== Entering application hipe
make[3]: Entering directory `/var/tmp/pkgbuild-0/erlang/sparcv9/erlang-otp-73b4221/lib/hipe/misc'
erlc -W +debug_info +warn_exported_vars +warn_missing_spec +warn_untyped_record -o../ebin hipe_consttab.erl
make[3]: *** [../ebin/hipe_consttab.beam] Bus Error (core dumped)
make[3]: Leaving directory `/var/tmp/pkgbuild-0/erlang/sparcv9/erlang-otp-73b4221/lib/hipe/misc'
Why is this and what can I do to complete my Erlang build?
The reason that the build fails is due to a broken build environment.
In this specific case the Sun GCC build is being used. This particular version of GCC was compiled to use a mixture of the the GNU assembler and the Sun linker.
The Sparc platform is highly sensitive to alignment of code and it will fault (for example, with a bus error) if unaligned code is executed.
The GNU assembler used by the stock GCC build on Sparc Solaris 10 doesn't work so hard to automatically align functions generated by the compiler, leading to unaligned code.
The solution is to build your own GCC and make sure that you use the system assembler and linker; you can achieve this by using the following options to GCC's configure script:
--with-as=/usr/ccs/bin/as \
--without-gnu-as \
--without-gnu-ld \
--with-ld=/usr/ccs/bin/ld \
The resultant GCC build will generated properly aligned code and allow you to build Erlang successfully.

Resources