"""
Launches the target process after setting a breakpoint at a convenient
entry point.
"""
import argparse
from shlex import quote

import gdb

import pwndbg.commands
import pwndbg.elf
import pwndbg.events
import pwndbg.symbol

break_on_first_instruction = False


@pwndbg.events.start
def on_start():
    global break_on_first_instruction
    if break_on_first_instruction:
        spec = "*%#x" % (int(pwndbg.elf.entry()))
        gdb.Breakpoint(spec, temporary=True)
        break_on_first_instruction = False


parser = argparse.ArgumentParser(
    description="""
    Set a breakpoint at a convenient location in the binary,
    generally 'main', 'init', or the entry point."""
)
parser.add_argument(
    "args", nargs="*", type=str, default=None, help="The arguments to run the binary with."
)


@pwndbg.commands.ArgparsedCommand(parser)
def start(args=None):
    if args is None:
        args = []
    """
    Set a breakpoint at a convenient location in the binary,
    generally 'main', 'init', or the entry point.
    """
    run = "run " + " ".join(args)

    symbols = ["main", "_main", "start", "_start", "init", "_init"]

    for symbol in symbols:
        address = pwndbg.symbol.address(symbol, allow_unmapped=True)

        if not address:
            continue

        b = gdb.Breakpoint(symbol, temporary=True)
        gdb.execute(run, from_tty=False, to_string=True)
        return

    # Try a breakpoint at the binary entry
    entry(args)


parser = argparse.ArgumentParser(
    description="""
    Set a breakpoint at the first instruction executed in
    the target binary.
    """
)
parser.add_argument(
    "args", nargs="*", type=str, default=None, help="The arguments to run the binary with."
)


@pwndbg.commands.ArgparsedCommand(parser)
@pwndbg.commands.OnlyWithFile
def entry(args=None):
    if args is None:
        arg = []
    """
    Set a breakpoint at the first instruction executed in
    the target binary.
    """
    global break_on_first_instruction
    break_on_first_instruction = True
    run = "run " + " ".join(map(quote, args))
    gdb.execute(run, from_tty=False)

@@ -101,16 +101,58 @@
 rgparse%0A
+from argparse import RawTextHelpFormatter%0A
 from shl
@@ -551,16 +551,118 @@
 False%0A%0A%0A
+# Starting from 3rd paragraph, the description is%0A# taken from the GDB's %60starti%60 command description%0A
 parser =
@@ -711,33 +711,56 @@
 %22%22%22%0A
-    Set a breakpoint
+Start the debugged program stopping
  at 
-a
+the first
  con
@@ -779,79 +779,623 @@
 tion
- in the binary,%0A    generally 'main', 'init', or the entry point.%22%22%22
+%0Afrom this list: main, _main, start, _start, init or _init.%0AYou may specify arguments to give it.%0A%0AArgs may include %22*%22, or %22%5B...%5D%22; they are expanded using the%0Ashell that will start the program (specified by the %22$SHELL%22 environment%0Avariable).  Input and output redirection with %22%3E%22, %22%3C%22, or %22%3E%3E%22%0Aare also allowed.%0A%0AWith no arguments, uses arguments last specified (with %22run%22 or%0A%22set args%22).  To cancel previous arguments and run with no arguments,%0Ause %22set args%22 without arguments.%0A%0ATo start the inferior without using a shell, use %22set startup-with-shell off%22.%0A%22%22%22,%0A    formatter_class=RawTextHelpFormatter,
 %0A)%0A
+%0A
 pars
@@ -1614,135 +1614,8 @@
  %5B%5D%0A
-    %22%22%22%0A    Set a breakpoint at a convenient location in the binary,%0A    generally 'main', 'init', or the entry point.%0A    %22%22%22%0A
     
@@ -2046,150 +2046,968 @@
 )%0A%0A%0A
-parser = argparse.ArgumentParser(%0A    description=%22%22%22%0A    Set a breakpoint at the first instruction executed in%0A    the target binary.%0A    %22%22%22
+# Starting from 3rd paragraph, the description is%0A# taken from the GDB's %60starti%60 command description%0Aparser = argparse.ArgumentParser(%0A    description=%22%22%22%0AStart the debugged program stopping at its entrypoint address.%0AYou may specify arguments to give it.%0A%0ANote that the entrypoint may not be the first instruction executed%0Aby the program. If you want to stop on the first executed instruction,%0Ause the GDB's %60starti%60 command (added in GDB 8.1).%0A%0AArgs may include %22*%22, or %22%5B...%5D%22; they are expanded using the%0Ashell that will start the program (specified by the %22$SHELL%22 environment%0Avariable).  Input and output redirection with %22%3E%22, %22%3C%22, or %22%3E%3E%22%0Aare also allowed.%0A%0AWith no arguments, uses arguments last specified (with %22run%22 or%0A%22set args%22).  To cancel previous arguments and run with no arguments,%0Ause %22set args%22 without arguments.%0A%0ATo start the inferior without using a shell, use %22set startup-with-shell off%22.%0A%22%22%22,%0A    formatter_class=RawTextHelpFormatter,
 %0A)%0Ap
@@ -3258,105 +3258,8 @@
  %5B%5D%0A
-    %22%22%22%0A    Set a breakpoint at the first instruction executed in%0A    the target binary.%0A    %22%22%22%0A
     

improve start and entry commands description (#1109)