How to set a breakpoint with lldb + mono - debugging

I have the following C# program (test.cs) which I want to debug:
using System;
using System.Collections.Generic;
class Program
{
static void Main(string[] args)
{
Console.WriteLine( "Hello, World!" );
List<int> list = new List<int>();
list.Add(123);
list.Add(234);
list.Add(345);
list.Add(456);
int number = 4;
++number;
Console.WriteLine(" number " + number); // <--- L:16 I want to set a breakpoint here :)
Console.WriteLine("Number of elements" + list.Count);
foreach (Object obj in list)
{
Console.WriteLine(" " + obj);
}
Console.WriteLine("Bye");
}
}
And below is the debug session using lldb and mono (I am in OSX). I can start the session and run the program however I am not able to setup any breakpoint. I guess that when using mono as the executable file things are different. How can I achieve this?
$ mcs -debug test.cs
$ lldb
(lldb) target create mono
Current executable set to 'mono' (i386).
(lldb) b test.cs:16
Breakpoint 1: no locations (pending).
WARNING: Unable to resolve breakpoint to any actual locations.
(lldb) run --debug test.exe
Process 15191 launched: '/usr/bin/mono' (i386)
Hello, World!
number 5
Number of elements4
123
234
345
456
Bye
Process 15191 exited with status = 0 (0x00000000)
(lldb)
I've tried with GBD as this old guide suggests but it is worse, apparently there is something broken in mono in OSX that makes it impossible to debug unless the soft debugger is used (which is exactly what I want to avoid. MonoDevelop debugger is really really unstable/unreliable/slow). This is what I have tried with GBD. No luck at all.
And help is appreciated.

Isn't mono the interpreter for your language and test.exe the binary? lldb only knows about mono -- any breakpoints you try to set would be in the mono interpreter. e.g. if you were debugging an issue with mono itself.
This is a unique enough environment that you'll need to do a little analysis to understand what lldb sees. What do you get for
(lldb) image list test.exe
? Of course if you do
(lldb) im li mono
You'll see mono listed -- because that's a binary that lldb knows about. (you can use plain image list aka im li to see all the binaries that lldb knows)
You can ask lldb to list all of the line table entries based on a source filename with a command line
(lldb) target modules dump line-table test.cs
if lldb has any debug information for a test.cs, you'll see a line table. Without a line table, file and line breakpoints (b test.cs:16) won't work.
For what it's worth, I don't think trying to use lldb (or gdb) to debug your C# program will work. You'll probably need to use some facility of the mono runtime itself to set breakpoints and examine program state.

Related

How to print source file name with dladdr() function?

I was trying to print a backtrace using dladdr(). info.dli_fname in the following code snippet is displaying the file name of an ELF file. Could you please tell me if it is possible to resolve and print the name of the source file and line number programmatically without the help of addr2line or gdb?
Code:
void print_caller(void)
{
int rc = -1;
Dl_info info = {0};
void *pc = __builtin_return_address(0);
rc = dladdr(pc, &info);
printf(" ==> %p: %s (in %s)\n", pc, info.dli_sname, info.dli_fname);
}
Output:
$ ./a.out
==> 0x55a6b04a1589: foo2 (in ./a.out)
tell me if it is possible to resolve and print the name of the source file and line number programmatically
It is definitely possible -- addr2line and gdb do that.
But it is very non-trivial -- it requires understanding and decoding (possibly multiple) complicated debugging info formats.
If you only care about a single platform (looks like Linux), things are a bit easier -- you only need to decode DWARF.
But that format is still pretty complicated. You should start with a helper library, such as libdwarf.

How do I configure CLion standard console output?

Problem:
CLion doesn't output any console output for debugging purposes.
I'm using CLion with the MingW compiler and cmake. No matter whether I use:
std::cout << "Testing" << std::endl;
Or:
printf("Testing");
I don't see any console output.
Attempts at Resolution:
1:
I've checked "Run", "Debug", "Terminal" and "Cmake". I've attempted to edit my configurations but "Debug" doesn't show up.
2:
Next, I went to Settings->Build,Execution,Deployment->CMake to edit the Generation types. I added Debug and RelWithDebInfo and still to no avail.
3:
I also attempted to add "-Debug" to Cmake, but I still have no output.
4:
The closest thing I've received for debugging is using GDB to view variable values at break points. This only works in the "RelWithDebInfo" generation.
Solution:
I ended up figuring out what the problem was.
I'm developing a Qt GUI application within CLion on Windows. You have to specify a console for console output to print onto.
Call this Console() function early in your main for a console prompt to open up. Now, whenever you run
QDebug() << <string>;
or
std::cout << <string> std::endl;
You'll see your debugging statements. Hope this helps somebody else out there with the same problem.
Code:
void Console()
{
AllocConsole();
FILE *pFileCon = NULL;
pFileCon = freopen("CONOUT$", "w", stdout);
COORD coordInfo;
coordInfo.X = 130;
coordInfo.Y = 9000;
SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coordInfo);
SetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE),ENABLE_QUICK_EDIT_MODE| ENABLE_EXTENDED_FLAGS);
}
Source:
I found a solution here:
[0] Console output in a Qt GUI app?
There's a simpler solution that doesn't require adding any code. Simply add the following environment variable in your debug configuration:
QT_ASSUME_STDERR_HAS_CONSOLE=1
With this, CLion shows QDebug and QML's console.*() when started with a debugger.

Debugging with GDB - seeing code around a given breakpoint

I am trying to debug a C++ program using GDB. I have set 15 breakpoints. Most of the breakpoints are in different files. After the first 5 breakpoints, it became difficult to remember what line of code any given breakpoint refers to.
I struggle quite a bit simply trying to recall what a given breakpoint refers to. I find this quite distracting. I was wondering if there is a way to tell gdb to display code around a certain breakpoint.
Something like this - $(gdb) code 3 shows 30 lines of code around breakpoint 3. Is this possible today. Could you please show me how?
I run gdb in tui mode, and I also keep emacs open to edit my source files.
You can use gdb within emacs.
In emacs, type M-x gdb, after entering the name of the executable, type M-x gdb-many-windows. It brings up an IDE-like interface, with access to debugger, locals, source, input/output, stack frame and breakpoints.
You can find a reference and snapshot here.
I don't think you can do it exactly like this in gdb as such, but it can be scripted in gdb python.
This crude script should help:
import gdb
class Listbreak (gdb.Command):
""" listbreak n Lists code around breakpoint """
def __init__ (self):
super(Listbreak, self).__init__ ("listbreak", gdb.COMMAND_DATA)
def invoke (self, arg, from_tty):
printed = 0
for bp in gdb.breakpoints():
if bp.number == int(arg[0]):
printed = 1
print ("Code around breakpoint " + arg[0] + " (" + bp.location + "):")
gdb.execute("list " + bp.location)
if printed == 0:
print ("No such breakpoint")
Listbreak()
Copy this to listbreak.py, source it in gdb (source listbreak.py), then use it like this:
listbreak 2

Pyclewn: Cfile appears last in the debugger when mapping several commands

I would like to use pyclewn in vim in order to debug some of my C++ code. In order to make my day easier I would like to map several commands to one key, for example:
au BufNewFile,BufRead *.cxx,*.cpp,*.c noremap <F6>
\:Pyclewn <CR> :Cfile %<<CR> :Cbreak main <CR>
As stated in the manual, I need to have the async keword set, so I have
let g:pyclewn_args = "--gdb=async"
in my ~\.vimrc file. However, when pressing F6, the gdb will load the file after all the other commands like this
Pyclewn version 1.11.py2 starting a new instance of gdb.
GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1
(...)
(gdb) break main
No symbol table is loaded. Use the "file" command.
(gdb) file foo
Reading symbols from foo...done.
(gdb)
How can I force file foo to come before other commands in the debugger?
So, just changed to pyclewn 2.0, in which I don't have the problem any more

Buffer Overflow Works in GDB but not in Terminal

I am using Mac OSX. I have created a buffer overflow vulnerable program:
#include<stdio.h>
#include<string.h>
int neverCalled() {
puts("You got me to be called");
return 0;
}
int main() {
puts("Name: ");
char name[64];
gets(name);
return 0;
}
I also have created an input file containing 88 "A"s (0x414141...) and 0x700E000001000000
When run in gdb:
(gdb) run < input
I get the output: You got me to be called and then a EXC_BAD_ACCESS error. Meaning that I exploited the program successfully.
When run it in terminal:
$ ./vulnerable < input
I get the output: Segmentation fault: 11 and nothing more.
Why does my buffer overflow work in gdb but fail in normal terminal.
gdb on mac os X appears to disable address space layout randomization
http://reverse.put.as/2011/08/11/how-gdb-disables-aslr-in-mac-os-x-lion/
Why 0x700E000001000000? Your exploit seems to be layout-specific, probably out of what gdb prints when typing "p neverCalled".
This is not guaranteed in all executions. As cabellicar123 correctly pointed out, the layout where libraries and executable are mapped in a process are randomized and not guaranteed to be the same between executions.
For some reason it seems that gdb always gets the same layout. As an exercise include "printf("%p"\n", neverCalled)" somewhere in your program and see how the value changes.

Resources