Is there a way to don't exit on ncurses initscr error? - ncurses

Ncurses initscr() on errors just exits the program.
Is there a way to trap the error?
I red all the manual on ncurses, but all say that iniscr just don't give possibility.

Use newterm instead of initscr if you are concerned about error handling. On error, newterm returns a null pointer (and does not exit).

Related

What mechanism does gdb use to know where to "finish" a function call?

In gdb, when debugging inside a function, we can use "finish" command to run to the end of a function.
My question is: how does gdb know the ending position of a function, especially when there's no debugging symbol to match source code "{}"?
I guess gdb looks for either "leave" or "mov %rbp, %rsp,pop %rbp" under x86 in order to judge whether it has reached the end of a function.
But the problem is,
(1) There're still some extra registers that needs to push/pop at the begin/end of a function call, depending on source code and ABI structure.
(2)The number of registers needs to be push/pop is decided during compilation phase, and I'm afraid this "number" information is not available throw binary executable file.
So, how does gdb determine, where is the end of a function call, so that "finish" command can jump to it?
Thanks!
gdb doesn't try to analyze the machine code. Instead, it unwinds the stack, finds the caller's PC, and sets a temporary breakpoint there. Then it lets the inferior run until the breakpoint is hit.
Due to the way gdb's unwinder is designed, this automatically handles finish from an inlined function as well (though there are still a few special cases in the code due to this).

How to handle "An unknown error occurred" when running a Rust program?

I am currently running cargo run and getting the most generic error, An unknown error has occurred.
When I then run cargo run --verbose I get Process didn't exit successfully: 'target/debug/ok_rust' (signal: 11) which I have no clue how to handle.
How do I debug this? What am I supposed to do? Test it with the nightly version, but the same libraries? How am I supposed to know if I'm responsible or if it's Rust?
According to the error you provided, this is not a problem with tooling (that is, Cargo and rustc both work correctly) but with your program:
Process didn't exit successfully: 'target/debug/ok_rust' (signal: 11)
Signal 11 means that a segmentation fault has happened in the program. Segfaults usually happen when invalid memory is accessed, for example, when a destroyed object is read. Rust is explicitly designed to avoid segfaults; if one happens, it means that one of the unsafe blocks in your program contains an error. This unsafe block may be the one you have written yourself or it may be in one of the libraries you use.
Anyway, you need to find the exact place where the segfault happens. You can use a debugger (gdb or lldb, depending on your system) or you can add debug output to your program, with which you will likely be able to pinpoint the problematic line. Then you'll need to trace the problem back to one of the unsafe blocks. For example, if you find that the segfault happens when accessing a value through a reference, like
let x = some_struct.field;
where some_struct: &SomeStruct, then it is likely that some_struct points to an invalid object; this can only happen if some_struct was created in an unsafe block, so you need to find where some_structs originates.

How can I force a process to return from a call to select() while debugging it

I'm running a server under gdb, and it's currently blocked in a call to select.
I want to make it return from select, after which I can manually modify the fd sets and see how execution continues.
I tried to put a breakpoint on the next line after the call to select(), and issued the command 'signal SIGINT', but that did nothing other than printing 'Continuing with signal SIGINT'.
edit: I'm actually debugging using vgdb, maybe that's the issue?
You could try the jump command. This takes a location similar to how break takes a location, so you can specify a line, or an address as *ADDR. Try help jump at the gdb prompt for more information.
I've generally had most success with this command when the distance that I jump is small, otherwise, too much program state is incorrect for the program to do anything sane, but jumping out of a system call, especially if the plan is to patch up the return state anyway might work well.
Valgrind gdbserver+vgdb only partially supports the GDB command 'signal sig'
since version 3.11 (which was just released the 23 September 2015.
Version 3.10 and before are completely ignoring the GDB instruction
to continue with a signal or to change the signal.
In release 3.11, 'signal SIG' is partially supported: if the process
reported a signal to GDB, the signal can be ignored (using signal 0)
or can be changed (using signal othersignr).
Valgrind gdbserver does currently not support to raise a signal from GDB.
Also, when a thread is blocked in a system call, the Valgrind gdbserver
will not accept the GDB instruction to 'jump' out or 'return' from the
syscall.

Interfacing with the code which calls select()

I'm writing a Haskell binding to some the library and there is a function void foo(), which calls select() inside. When i call this function from Haskell, that select() call starts to constantly return EINTR. This confuses library code and it starts looping forever.
In the #haskell IRC channel i've been told to run foo() from a bound thread. I've used runInBoundThread for this and now everything seems to work. But in some rare cases i'm getting Alarm clock message in the console (Ok, i've found it means that app catches SIGALRM).
I'm not sure it's proper way to handle this problem and i don't want to depend on Control.Concurrency. What should i do?
The cause of SIGALRM was GHC's runtime using old codepath for managing timer stuff. This old codepath was turning on because GHC's configure script had sort of linuxism in its check for create_timer() function. Fixing it made GHC use the same mechanism that is used on all platforms, and eliminated the error in question.
Relevant commit: https://gitlab.haskell.org/ghc/ghc/-/commit/edc059a425068f9bf4a60520e8d8906bc764e2b5
n.m.'s comment is correct: the code in withRTSSignalsBlocked will hide signals from your ffi'd code: http://hackage.haskell.org/packages/archive/HDBC-mysql/0.6.6.1/doc/html/Database-HDBC-MySQL.html#v:withRTSSignalsBlocked
This should also eliminate the need for runInBoundThread, I think.

Can I instruct gdb to run commands in response to SIGTRAP?

I'm debugging a reference leak in a GObject-based application. GObject has a simple built-in mechanism to help with such matters: you can set the g_trap_object_ref variable in gobject.c to the object that you care about, and then every ref or unref of that object will hit a breakpoint instruction (via G_BREAKPOINT()).
So sure enough, the program does get stopped, with gdb reporting:
Program received signal SIGTRAP, Trace/breakpoint trap.
g_object_ref (_object=0x65f090) at gobject.c:2606
2606 old_val = g_atomic_int_exchange_and_add ((int *)&object->ref_count, 1);
(gdb) _
which is a great start. Now, normally I'd script some commands to be run at a breakpoint I manually set using commands 3 (for breakpoint 3, say). But the equivalent for SIGTRAP, namely handle SIGTRAP, doesn't give me the option of doing anything particularly interesting. Is there a good way to do this?
(I'm aware that there are other ways to debug reference leaks, such as setting watchpoints on the object's ref_count field, refdbg, scripting regular breakpoints on g_object_ref() and g_object_unref(). I'm about to go try of those now. I'm looking specifically for a way to script a response to SIGTRAP. It might come in useful in other situations, too, and I'd be surprised if gdb doesn't support this.)
Do you want to show some values and continue execution of the program? In that case, just define a macro that displays the values you're interested in, continues execution and calls itself recursively:
define c
echo do stuff\n
continue
c
end
GDB doesn't support it.
In general, attaching a command script to signal makes little sense -- your program could be receiving SIGTRAP in any number of places, and the command will not know whether a particular SIGTRAP came in in expected context or not.

Resources