代码运行触发exit code 139(SIGSEGV)错误,求排查原因及解决方案
问题:Python程序触发SIGSEGV错误(退出码139)
运行Python代码输入参数后立即报错:
Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)
已尝试gdb调试未获有效信息,怀疑第三方库导致,需排查原因及涉事库。
代码详情
import googlemaps import webbrowser from ortools.constraint_solver import routing_enums_pb2 from ortools.constraint_solver import pywrapcp import mysql.connector from dfs import depth_first_search from genetic import create_population, calculate_fitness, genetic_algorithm from timeWindowing import get_user_time_windows, group_packages_by_time_window from datetime import datetime, timedelta from gis import solve_gis_vrp, plot_optimal_route # Import the GIS-based functions from gis.py # Replace 'YOUR_API_KEY' with your Google Maps API Key gmaps = googlemaps.Client( key='my-api-key') # Specify your starting point starting_point = "Al Aqiq, Riyadh 13519, Saudi Arabia" # Global variables for addresses and coordinates_mapping addresses = {} coordinates_mapping = {} def get_coordinates_from_database(): try: connection = mysql.connector.connect( host='localhost', user='root', password='my-password', database='database-name', port= port-number ) cursor = connection.cursor() # Fetch full information from the database query_fetch_addresses = "SELECT id, building_number, postal_code, city, street_name, latitude, longitude, District, short_address FROM spl_api_data" cursor.execute(query_fetch_addresses) result = cursor.fetchall() if not result: print("No addresses found in the database.") return None global addresses addresses = {row[8]: row for row in result} # Using short_address as a key return addresses except mysql.connector.Error as err: print("MySQL Error: {}".format(err)) return None finally: if connection.is_connected(): cursor.close() connection.close() def open_google_maps_url(starting_point, coordinates): google_maps_url = f"https://www.google.com/maps/dir/{starting_point}/" + "/".join( [f"{lat},{lng}" for lat, lng in coordinates]) webbrowser.open(google_maps_url) def calculate_distance(lat1, lon1, lat2, lon2): from math import radians, sin, cos, sqrt, atan2 lat1, lon1, lat2, lon2 = map(radians, [lat1, lon1, lat2, lon2]) dlat = lat2 - lat1 dlon = lon2 - lon1 a = sin(dlat / 2) ** 2 + cos(lat1) * cos(lat2) * sin(dlon / 2) ** 2 c = 2 * atan2(sqrt(a), sqrt(1 - a)) return 6371 * c # Radius of Earth in kilometers def solve_vrp_with_traffic(starting_point, destination_coordinates, user_time_windows): manager = pywrapcp.RoutingIndexManager(len(destination_coordinates), 1, 0) routing = pywrapcp.RoutingModel(manager) coordinates = [(float(row[5]), float(row[6])) for row in destination_coordinates] distance_matrix = [[0] * len(coordinates) for _ in range(len(coordinates))] for i in range(len(coordinates)): for j in range(len(coordinates)): if i != j: lat1, lon1 = coordinates[i] lat2, lon2 = coordinates[j] distance_matrix[i][j] = calculate_distance(lat1, lon1, lat2, lon2) def distance_callback(from_index, to_index): from_node = manager.IndexToNode(from_index) to_node = manager.IndexToNode(to_index) directions_result = gmaps.directions( f"{coordinates[from_node][0]}, {coordinates[from_node][1]}", f"{coordinates[to_node][0]}, {coordinates[to_node][1]}", mode="driving", departure_time="now", traffic_model="best_guess", ) return directions_result[0]["legs"][0]["duration_in_traffic"]["value"] transit_callback_index = routing.RegisterTransitCallback(distance_callback) routing.SetArcCostEvaluatorOfAllVehicles(transit_callback_index) search_parameters = pywrapcp.DefaultRoutingSearchParameters() search_parameters.first_solution_strategy = ( routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC ) solution = routing.SolveWithParameters(search_parameters) if solution: index = routing.Start(0) route = [] while not routing.IsEnd(index): node_index = manager.IndexToNode(int(index)) route.append(node_index) index = int(solution.Value(routing.NextVar(index))) current_location = starting_point optimized_route = [destination_coordinates[index][8] for index in route] open_google_maps_url(starting_point, coordinates) return optimized_route else: print("VRP solution not found.") return None def solve_combined(starting_point, destination_coordinates, user_time_windows): global coordinates_mapping coordinates_mapping = {addr[8]: (float(addr[5]), float(addr[6])) for addr in destination_coordinates} grouped_packages = group_packages_by_time_window(user_time_windows, addresses) optimized_routes = [] for group in grouped_packages: if len(group) > 1: print(f"Delivering Group: {', '.join([addr[0] for addr in group])} together") routes = solve_vrp_with_traffic(starting_point, [addresses.get(addr[0]) for addr in group], user_time_windows) optimized_routes.append(routes) else: print(f"Delivering Single: {group[0][0]}") routes = solve_vrp_with_traffic(starting_point, [addresses.get(group[0][0])], user_time_windows) optimized_routes.append(routes) # Apply genetic algorithm to further optimize routes for i in range(len(optimized_routes)): if optimized_routes[i]: # Create population for genetic algorithm population = create_population(num_individuals=5, num_genes=len(optimized_routes[i])) # Create distance matrix for genetic algorithm distance_matrix = [[0] * len(optimized_routes[i]) for _ in range(len(optimized_routes[i]))] for j in range(len(optimized_routes[i])): for k in range(len(optimized_routes[i])): if j != k: distance_matrix[j][k] = calculate_distance( coordinates_mapping[optimized_routes[i][j]][0], coordinates_mapping[optimized_routes[i][j]][1], coordinates_mapping[optimized_routes[i][k]][0], coordinates_mapping[optimized_routes[i][k]][1] ) # Run genetic algorithm optimized_genetic_route = genetic_algorithm(population, distance_matrix, num_generations=50) # Update the route with the optimized genetic route optimized_routes[i] = [optimized_routes[i][idx] for idx in optimized_genetic_route.genes] return optimized_routes def main(): global addresses addresses = get_coordinates_from_database() if not addresses: return print("Available Short Addresses:") for short_address in addresses: print(short_address) num_packages = int(input("How many packages will be delivered? ")) if num_packages <= 0: print("Invalid number of packages.") return chosen_short_addresses = [] for i in range(1, num_packages + 1): chosen_short_address = input(f"Enter the short address {i}: ") chosen_short_addresses.append(chosen_short_address) user_time_windows = get_user_time_windows(chosen_short_addresses, addresses) destination_coordinates = [addresses.get(short_address) for short_address in chosen_short_addresses] if None in destination_coordinates: print("Invalid short address.") return grouped_packages = group_packages_by_time_window(user_time_windows, addresses) # Call the GIS-based optimization function optimal_route = solve_gis_vrp(list(coordinates_mapping.values())) print("Chosen Route (GIS Algorithm):") if optimal_route: plot_optimal_route(list(coordinates_mapping.values()), optimal_route) else: print("No valid route found within the specified time windows.") if __name__ == "__main__": main()
排查思路与解决方案
可能涉事的第三方库
SIGSEGV是内存非法访问错误,通常由底层C/C++编写的Python扩展库引发,结合代码重点排查:
- ortools:
pywrapcp是C++实现的VRP求解模块,参数异常或内存管理问题易触发崩溃 - mysql.connector:数据库连接的底层C实现可能存在内存泄漏或非法访问
- 自定义gis模块:若
solve_gis_vrp/plot_optimal_route依赖GDAL/GEOS等GIS C库,也可能引发问题
分步排查步骤
隔离崩溃点
- 注释
main函数中solve_gis_vrp和plot_optimal_route的调用,运行程序验证是否崩溃 - 若恢复正常,问题出在自定义GIS模块,检查其中的C扩展调用或内存操作
- 若仍崩溃,继续注释遗传算法、ortools相关代码,逐步定位触发崩溃的函数
- 注释
修复ortools参数异常
当destination_coordinates长度为1时,RoutingIndexManager初始化的节点数为1,无有效路径可求解,会触发底层断言失败:def solve_vrp_with_traffic(starting_point, destination_coordinates, user_time_windows): if len(destination_coordinates) < 2: return [destination_coordinates[0][8]] if destination_coordinates else None manager = pywrapcp.RoutingIndexManager(len(destination_coordinates), 1, 0) # 后续代码保持不变修复数据库连接资源释放
get_coordinates_from_database中connection未初始化时,finally块的connection.is_connected()会触发非法访问:def get_coordinates_from_database(): connection = None try: connection = mysql.connector.connect( host='localhost', user='root', password='my-password', database='database-name', port= port-number ) # 后续代码保持不变 except mysql.connector.Error as err: print("MySQL Error: {}".format(err)) return None finally: if connection is not None and connection.is_connected(): cursor.close() connection.close()排查自定义模块
- 临时替换
dfs、genetic、timeWindowing的实现为占位代码,验证是否崩溃 - 检查gis模块中是否存在内存越界、空指针访问等问题
- 临时替换
环境版本验证
- 检查ortools、mysql.connector的版本兼容性,尝试降级/升级到稳定版本
- 确认Python版本与第三方库的适配性(如ortools对Python3.11+的支持情况)
内容的提问来源于stack exchange,提问作者user31081998
相关产品推荐
相关产品推荐

