1

Consider the following simple program for GCC:

#include <stdio.h>

int calledtest(int a)
{
    return(a + 5);
}

asm(
    ".pushsection .text;"
    ".type calltest, @function;"
    "calltest:"
    "  call calledtest;"
    "  ret;"
    ".size calltest, .-calltest;"
    ".popsection;"
);

int calltest(int);

int main(int argc, char **argv)
{
    printf("%i\n", calltest(2));
    return(0);
}

This program works as expected and all that, but my problem is that, when running it in gdb, gdb does not understand how to "step into" the calltest function. Running the step command on the printf line simply steps right into printf, skipping the calltest call entirely. Do note that stepping into calltest itself isn't really a problem for me in my current use-case, but what bothers me all the much more is that gdb even skips the whole call to calledtest. I can of course get into calltest and calledtest by stepping instructions, but that can be pretty tedious, especially when calltest is called on a line with complex expressions and/or other function calls.

If I put the calltest function into its own, separate assembly file that I compile with GAS, I can simply pass the -g flag to GAS and gdb will work entirely as expected, but I'm not aware of any way to make GCC do anything similar with inline assembly, and I do need inline assembly since I generate these little stubs of mine with CPP macros as part of a greater library.

It appears to me that this is possible to fix somehow, since calltest seems to be very similar to the standard PLT stubs that gdb certainly has no trouble with, but I don't know how debug info is generated for those.

So my question is twofold: First, what kind of information is it that gdb is really looking for to "understand" these functions, and, second, how can I generate it?

4
  • Maybe you should have a normal C function definition for calltest, and put the asm() as the body of the function. Commented Dec 16, 2016 at 21:22
  • @Barmar: Ordinarily I might agree, but in reality I use these stubs a bit differently. Specifically, I jump to a target function rather than call it (similar to the PLT stubs, or an optimized tail-call). Commented Dec 16, 2016 at 21:39
  • I suspect the problem is that asm() doesn't put calltest in the debugging information, which is what the debugger uses. Commented Dec 16, 2016 at 21:41
  • @Barmar: Indeed. The question is how to do that manually. Commented Dec 16, 2016 at 21:42

1 Answer 1

3

.loc and .cfi_* directives seem to do it. For .loc to work I had to put each instruction into a separate line:

asm(
    ".pushsection .text\n"
    ".type calltest, @function\n"
    "calltest:\n"
    ".loc 1 14 0\n"
    ".cfi_startproc\n"
    "  call calledtest\n"
    "  ret\n"
    ".cfi_endproc\n"
    ".size calltest, .-calltest\n"
    ".popsection\n"
);
Sign up to request clarification or add additional context in comments.

3 Comments

In actual fact, the .loc directive alone seems to be enough. I had already tried the CFI stuff and had it make no difference. Annoyingly enough, though, when compiling with certain optimization flags (-Ofast -march=native, in my case), it seems that GCC will move the assembly block to before it has assigned the filename, which makes the .loc directive fail, so I'm not sure how to make that robust. But it does answer the question, so thanks!
@Dolda2000 The actual fact is that .cfi directivers are required, that GCC will never re-arrange inline assembly, and the .loc directives are entirely optional. You appear to have come to a whole bunch of incorrect conclusions.
@EmployedRussian: I don't believe so. It is well-known that GCC is allowed to re-order top-level parts of the program when optimization is turned on, so the inline assembly may well be reordered with regard to other parts of the program. In this case, checking the intermediate assembly output from GCC confirms that that does indeed happen. As for what directives are "required", I can only present the empirical observation that gdb works as expected when .loc directives are included, but not when only .cfi directives are included. Not sure how "incorrect conclusions" can be drawn from that.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.