/*
* Copyright 2015 Steven Watanabe
* Distributed under the Boost Software License, Version 1.0.
- * (See accompanying file LICENSE_1_0.txt or copy at
- * http://www.boost.org/LICENSE_1_0.txt)
+ * (See accompanying file LICENSE.txt or copy at
+ * https://www.bfgroup.xyz/b2/LICENSE.txt)
*/
#include "debugger.h"
#include "pathsys.h"
#include "cwd.h"
#include "function.h"
+#include "mem.h"
+#include "startup.h"
#include <assert.h>
#include <stdarg.h>
#include <stdlib.h>
#include <unistd.h>
#endif
+#include <string>
+#include <vector>
+
#undef debug_on_enter_function
#undef debug_on_exit_function
fputc( '\0', out );
}
-static char * debug_string_read( FILE * in )
+static std::string debug_string_read( FILE * in )
{
string buf[ 1 ];
int ch;
- char * result;
+ std::string result;
string_new( buf );
while( ( ch = fgetc( in ) ) > 0 )
{
string_push_back( buf, (char)ch );
}
- result = strdup( buf->value );
+ result = buf->value;
string_free( buf );
return result;
}
{
int len;
int i;
- int ch;
LIST * result = L0;
- fscanf( in, "%d", &len );
- ch = fgetc( in );
- assert( ch == '\n' );
- for ( i = 0; i < len; ++i )
+ int ret = fscanf( in, "%d", &len );
+ if (ret == 1)
{
- result = list_push_back( result, debug_object_read( in ) );
+ int ch = fgetc( in );
+ if (ch > 0) assert( ch == '\n' );
+ for ( i = 0; i < len; ++i )
+ {
+ result = list_push_back( result, debug_object_read( in ) );
+ }
}
return result;
}
*/
typedef struct _frame_info
{
- OBJECT * file;
- int line;
- OBJECT * fullname;
+ OBJECT * file = nullptr;
+ int line = 0;
+ OBJECT * fullname = nullptr;
LOL args[ 1 ];
- char * rulename;
-} FRAME_INFO;
+ std::string rulename;
-static void debug_frame_info_free( FRAME_INFO * frame )
-{
- object_free( frame->file );
- object_free( frame->fullname );
- lol_free( frame->args );
- free( frame->rulename );
-}
+ _frame_info()
+ {
+ lol_init( args );
+ }
+
+ ~_frame_info()
+ {
+ if ( file ) object_free( file );
+ if ( fullname ) object_free( fullname );
+ lol_free( args );
+ }
+} FRAME_INFO;
static void debug_frame_read( FILE * in, FRAME_INFO * frame )
{
const char * root = object_str( cwd() );
path_parse( object_str( filename ), path1 );
path1->f_root.ptr = root;
- path1->f_root.len = strlen( root );
+ path1->f_root.len = int32_t(strlen( root ));
string_new( buf );
path_build( path1, buf );
result = object_new( buf->value );
}
}
-static void debug_print_frame_info( FRAME_INFO * frame )
+static void debug_print_frame_info( FRAME_INFO & frame )
{
- OBJECT * file = frame->file;
+ OBJECT * file = frame.file;
if ( file == NULL ) file = constant_builtin;
- printf( "%s ", frame->rulename );
- if ( strcmp( frame->rulename, "module scope" ) != 0 )
+ printf( "%s ", frame.rulename.c_str() );
+ if ( frame.rulename != "module scope" )
{
printf( "( " );
- if ( frame->args->count )
+ if ( frame.args->count )
{
- lol_print( frame->args );
+ lol_print( frame.args );
printf( " " );
}
printf( ") " );
}
- printf( "at %s:%d", object_str( file ), frame->line );
+ printf( "at %s:%d", object_str( file ), frame.line );
}
static void debug_mi_print_frame_info( FRAME_INFO * frame )
{
printf( "frame={func=\"%s\",args=[],file=\"%s\",fullname=\"%s\",line=\"%d\"}",
- frame->rulename,
+ frame->rulename.c_str(),
object_str( frame->file ),
object_str( frame->fullname ),
frame->line );
static void debug_child_kill( int argc, const char * * argv )
{
- exit( 0 );
+ b2::clean_exit( 0 );
}
static int debug_add_breakpoint( const char * name )
long line = strtoul( ptr + 1, &end, 10 );
if ( line > 0 && line <= INT_MAX && end != ptr + 1 && *end == 0 )
{
- OBJECT * file = object_new_range( file_ptr, ptr - file_ptr );
+ OBJECT * file = object_new_range( file_ptr, int32_t(ptr - file_ptr) );
return add_line_breakpoint( file, line );
}
else
long line = strtoul( ptr + 1, &end, 10 );
if ( line > 0 && line <= INT_MAX && end != ptr + 1 && *end == 0 )
{
- OBJECT * file = object_new_range( file_ptr, ptr - file_ptr );
+ OBJECT * file = object_new_range( file_ptr, int32_t(ptr - file_ptr) );
result = handle_line_breakpoint( file, line );
object_free( file );
}
DWORD result;
string_reserve( out, 256 + 1 );
string_truncate( out, 256 );
- while( ( result = GetModuleFileNameA( NULL, out->value, out->size ) ) == out->size )
+ while( ( result = GetModuleFileNameA( NULL, out->value, DWORD(out->size) ) ) == DWORD(out->size) )
{
string_reserve( out, out->size * 2 + 1);
string_truncate( out, out->size * 2 );
if ( debug_interface == DEBUG_INTERFACE_CONSOLE )
{
printf( "Breakpoint %d, ", id );
- debug_print_frame_info( &base );
+ debug_print_frame_info( base );
printf( "\n" );
debug_print_source( base.file, base.line );
}
debug_parent_forward_nowait( 3, new_args, 0, 0 );
debug_frame_read( command_child, &frame );
printf( "#%d in ", i );
- debug_print_frame_info( &frame );
+ debug_print_frame_info( frame );
printf( "\n" );
}
fflush( stdout );
fflush( command_output );
debug_parent_wait( 0 );
}
- exit( 0 );
+ b2::clean_exit( 0 );
}
static const char * const help_text[][2] =
}
debug_mi_format_token();
printf( "^exit\n" );
- exit( EXIT_SUCCESS );
+ b2::clean_exit( EXIT_SUCCESS );
}
static void debug_mi_gdb_set( int argc, const char * * argv )
debug_mi_format_token();
printf( "^done,threads=[{id=\"1\"," );
debug_mi_print_frame_info( &info );
- debug_frame_info_free( &info );
printf( "}],current-thread-id=\"1\"\n(gdb) \n" );
}
}
debug_mi_format_token();
printf( "^done,new-thread-id=\"1\"," );
debug_mi_print_frame_info( &info );
- debug_frame_info_free( &info );
printf( "\n(gdb) \n" );
}
}
debug_mi_format_token();
printf( "^done," );
debug_mi_print_frame_info( &info );
- debug_frame_info_free( &info );
printf( "\n(gdb) \n" );
}
}
{
int result;
size_t capacity = 8;
- char * * buffer = (char **)malloc( capacity * sizeof( char * ) );
- char * * current = buffer;
+ std::vector<char*> tokens;
+ tokens.reserve(capacity);
char * iter = line;
char * saved = iter;
- *current = iter;
for ( ; ; )
{
/* skip spaces */
++iter;
}
}
- /* resize the buffer if necessary */
- if ( current == buffer + capacity )
- {
- buffer = (char**)realloc( (void *)buffer, capacity * 2 * sizeof( char * ) );
- current = buffer + capacity;
- }
/* append the token to the buffer */
- *current++ = saved;
+ tokens.push_back(saved);
/* null terminate the token */
if ( *iter )
{
*iter++ = '\0';
}
}
- result = run_command( current - buffer, (const char **)buffer );
- free( (void *)buffer );
+ result = run_command( (int) tokens.size(), const_cast<const char **>( &tokens[0] ) );
return result;
}
int result;
int ch;
string line[ 1 ];
- string_new( line );
+ auto line_delete = b2::jam::make_unique_bare_jptr( line, string_new, string_free );
/* HACK: force line to be on the heap. */
string_reserve( line, 64 );
while( ( ch = fgetc( command_input ) ) != EOF )
}
}
result = process_command( line->value );
- string_free( line );
return result;
}
while ( debug_state == DEBUG_STOPPED )
{
if ( feof( command_input ) )
- exit( 1 );
+ b2::clean_exit( 1 );
fflush(stdout);
fflush( command_output );
read_command();