When a process is broken, the debugger looks at the PCB (process control block) to find out the location of the stack(s) (plural if multi-threading). The stack has a bunch of routine return addresses pushed onto it (for example in the cdecl calling convention the caller pushes the return address onto the stack before transferring control to the callee).

The debugger knows how to find the pushed routine return addresses of the stack. It knows how to do this due to some heuristics, as well as debug information (if it is available). But even if debug info isn’t available, it will use heuristics, though it can make mistakes (and thus the stack may be inaccurate).

Anyway, once the debugger has identified the return addresses on the stack, it will follow each one to the respective routine. It will then consult the debug info (if it is available), to find the name of those routines. And voila, you have the callstack. If the debug info isn’t available, the callstack will simply display addresses of the routines (as well as the dll that the routine is in).